class StaticCode
{
// 类的非静态成员变量(实例变量)定义语句:
// 作用:用来存储对象的特有数据的成员变量。
// 运行:当类对象被创建时就执行,按照顺序自上而下执行,和构造代码块平级。(即当有多个构造函数
// 代码块和多个非静态成员变量时,JVM按照自上而下的顺序来执行所有语句,包括构造代码块里的代码
// 和非静态成员的声明。)
// 存储位置:非静态变量位于堆内存中的对象实体中。
int num = 3;
// 构造代码块
{
System.out.println("a 我是"构造代码块",当类对象被创建时,按照顺序执行");
}
// 静态代码块。
// 作用:用来初始化类使用的。
// 运行:随着类的加载而执行,并且只执行一次,而且是自上向下执行的(即当有多个静态代码块,
// 和静态成员变量时,JVM自上向下执行每条语句。包括执行静态代码块里的代码,和根据静态成员的声明,
// 创建相应的变量)。
// 位置:其位于方法区(共享区、代码区)
// 注意:静态代码块和静态成员函数中只能使用静态成员,而不能使用非静态成员,原因是在使用(或执行)静态代码块
// 和静态成员函数时,非静态成员变量还没有被创建,因为只有在创建类对象时,非静态成员变量才在堆内存中被创建,
// 而之所以不能使用非静态成员函数,是因为非静态成员函数只能被类对象调用而不能被类名调用,所以,非静态成员中
// 是可以使用非静态成员变量的,所以如果静态代码块和静态成员函数若可以调用非静态成员函数,则会执行非静态成员
// 函数时,用到里面的非静态成员变量,而该非静态成员变量只有在创建类对象时才会被创建(才会存在)。所以就会导致
// 引用不存在的变量,出现错误。
static int age =10;
static
{
System.out.println("A:我是"静态代码块"!");
System.out.println("A:age : "+age);
}
// 构造代码块:
// 作用:用来初始化所有类对象的。
// 运行:在对象刚创建时就执行,优先于构造函数执行。
String name = "张三" ;
{
System.out.println("B:我是"构造代码块"!");
System.out.println("B:num : "+num);
System.out.println("B:name : "+name);
}
// 构造代码块
{
System.out.println("b 我是"构造代码块",当类对象被创建时,按照顺序执行");
}
// 构造函数:
// 作用:用来初始化类的对象。
// 运行:当类对象被创建时运行。
StaticCode()
{
// this.StaticCode(3);
System.out.println("C 我是类的"构造函数"!");
}
StaticCode(int x)
{
System.out.println("构造函数之间的调用!");
}
// 静态成员变量:又叫做类变量(区别于实例变量)
// 作用:用来存储被所有类对象所共享的数据
// 运行:随着类的加载就被创建了,直到类消失才会消失。生命周期最长。其可以直接用类名调用,即类名.静态成员变量名
// 存储:静态变量是位于方法区(共享区、代码区)
// 静态成员函数:
// 作用:不需要创建类对象就可以使用的功能(函数),即函数中没有使用类对象特有的数据,使用的都是
// 类对象共有的数据或其他数据。
// 运行:其可以直接用类名调用,即类名.静态成员函数名。也可以接受类对象调用,即类对象.静态成员函数
// 存储:其位于方法区(共享区、代码区)。
public static void show()
{
System.out.println("我是"静态成员函数"");
}
}
// StaticCodeDemo 为主类,即含有主函数的类,并且是JVM首先加载的类(即 java 主类),所有含有主函数的类都是可以
// 独立运行的类。主类除了要被JVM首先调用和其中必须含有主函数之外,其他地方都与一个普通的java类没有任何区别就
// 也可以被创建对象,而主函数(即main函数)也不过是其的一个静态方法而已,只不过这个方法是会被JVM调用。所以也
// 可以有构造函数,也可以创建对象,并用对象去调用主函数,也可以将对象传递出去。
class StaticCodeDemo
{
static int cnt = 0;
static
{
System.out.println("我是主类中的静态代码块,JVM首先需要将主类加载入内存中,从而引起我的执行,然后"+
"才能调用主类中的方法(即主函数main方法),即 主类名.main(String[]型的变量)");
}
{
System.out.println("--F--:构造代码块");
}
StaticCodeDemo()//构造函数的权限默认和类的权限一致,类是public,其就是public,类是private,其就是private。
{
System.out.println("--G--:构造函数");
}
public static void main(String[] args)
{
// JVM在运行主函数时,当首次使用到某类的时候,该类会被加载入内存,而编译的时候是不会将任何类加载进入内存的。
// 所以JVM会先将主类(主函数所在的类)加载入内存,然后再执行主函数,执行时若用到其他类的内容则会加载该类
// 进入内存,程序当中使用到类的内容的情况有两种,一种是,创建类对象(即 new 类名()),另一种是使用类名引用
// 静态成员(即 类名.静态成员)。
// 注意:创建类的引用(即 类名 类引用型变量名 = null),并不会使得类加载进入内存。因为创建引用并没有使用到
// 类定义中的任何信息。只是使用了类名,而类名会被解析成为一种自定义的类型名。任何类只有被加载入内存后,
// 才能使用里面的内容(包括创建类对象,因为创建类对象会使用到构造函数)。
// new StaticCode();
// System.out.println("--M--:主函数代码运行*******"+"cnt = "+cnt);
// String[] arr= null;
// if( cnt == 0 )
// {
// cnt++;
// new StaticCodeDemo().main(arr); //main方法只不过是一个很普通的函数,很普通的类中的一个公共静态函数
//// 只不过为了和JVM协同工作(即配合JVM的调用),所以要写成固定的格式
//// ,除此之外它完全符合一个类中的静态函数所具有的一切用法和特点。
//// 也完全可以被其他类的成员函数调用或自己调用自己(递归调用)。
// }
// else
// {
// if( cnt == 1)
// {
// cnt++;
// main(arr); //自己调用自己,递归调用
// }
// }
StaticCode.show();
}
}
|
|