类变量
类变量的内存布局
目前对于类变量的内存布局不能一概而论。
对于jdk8及其之前的版本,类变量放在方法区的静态域中。
对于之后版本的jdk而言,类变量放在堆区。
但实例化出的对象,类变量都是通过引用的。
无论如何有以下两个公示:
1.静态对象被所有对象共享。
2.static类变量,在类加载的时候就生成了。
类变量的使用细节
1.什么时候使用类变量?
当需要让某个类的所有对象都共享一个变量时,就可以考虑使用类变量。
2.类变量和实例变量的区别
类变量是该类的所有对象所共有的,而实例变量是每个对象独享的。
3.加上static称为类变量或静态变量,否则称为实例变量/普通变量/非静态变量。
4.类变量可以通过类名.类变量名,或对象名.类变量名来访问,但推荐使用类名.类变量名。
5.实例变量不能通过类名.类变量名访问。
6.类对象是在类加载时就初始化,故无创建对象时也可以使用,并随类消亡而消亡。
类方法
类方法和类变量大体是类似的,但关于方法上还是有一些小区别的。
1.类方法和类变量都是随着类加载而加载的,类变量可能存放在堆区或方法区的静态域中,但类方法是一定存放在方法区的。
2.类方法中无this和super参数。其实这个挺好理解的,this实质上就是实例化的对象的地址,而类方法不依赖于对象,所以类方法无this参数。而super也是和对象有关的关键字,相当于父类中的this。
3.类方法只能访问类变量和类方法。理由同上。
main方法
深入理解main方法,main方法形式为:public static void main(String[] args)
1.JAVA虚拟机需要调用类的main方法,所以该方法的访问权限必须使public。
2.JAVA虚拟机在执行main()方法时,不必创建对象,所以必须时static。
3.该方法接受String类型的数组参数,该数组保存执行JAVA命令时传递给所运行的类的参数。
特别提示:
由于main方法是静态方法,所以不能调用本类中非静态属性或方法,必须通过实例化出对象才能调用本类中的非静态成员。
代码块
基本介绍
代码块又称为初始化块,属于类中的成员,类似于方法,将逻辑语句封装在方法体中,用{}包围。
但和方法不同,没有方法名,没有返回,没有参数,只有方法体,而且不用通过对象或类显示调用,而是加载类时,或创建对象时隐式的调用。
基本语法
[修饰符]{
代码
};
注意:1.修饰符可选可不写,写的话只能写static.
2.代码块分为两类,加static为静态代码块,没有static修饰为普通代码块。
3.';'可以写上,也可以省略。
注意事项和细节
1.static代码块称为静态代码块,作用就是对类进行初始化,而且它随着类的加载而执行,并且只会执行一次。如果时普通对象,没创建一个对象就执行。(静态代码块就是将类加载进方法区时才执行,而普通代码块则是在堆区创建对象时才执行,两者服务的对象不同,一个是类,一个是对象。)
2.类什么时候被加载?
(1)创建对象实例时。
(2)创建子类对象实例,父类会优先加载。
(3)使用类的静态成员时。
类加载就是将类放入方法区,便于以后使用,所以在第一次用到该类的东西时,该类就会被加载,并且只会被加载一次,当有继承关系时,总是要寻根溯源,优先加载父类。
3.普通代码块,在创建对象实例时,会被隐式的调用。被创建一次,就会调用一次。如果知识使用类的静态成员或方法,普通代码块并不会执行,因为并没有涉及堆区对象的事情。
4.创建一个对象时,在一个类中,调用顺序是:
(1)调用静态代码块和静态属性初始化(同级按定义顺序);
(2)调用普通代码块和普通属性初始化;
(3)调用构造器。
5.构造器的最前面其实隐含了super()和调用普通代码块的语句,所以两者优先于当前构造器。
6.当一个子类对象被创建时,父类,子类的静态代码块,普通代码块,静态属性,普通属性,构造器的调用顺序如下:
首先是将父类和子类加载,而加载时先加载父类。
(1)父类的静态代码块和静态属性初始化。
(2)子类的静态代码块和静态属性初始化。
之后就是堆区的事情了,还是先父类再子类。
(3)父类的普通代码块和普通属性初始化。
(4)父类的构造器。
(5)子类的普通代码块和普通属性初始化。
(6)子类的构造器。
7.静态代码块只能调用静态成员,普通代码块可以调用所有成员。
静态就是类本身固有的属性,所以只能在类这一层面调用自己的资源,而普通的属于对象层面,属于个性的实例,所以可以调用所有的成员。
final关键字
final中文意思是最后的,在这里解释了不可修改的更佳。
final可以修饰类,方法,属性,局部变量。
以下位final的使用场景:
1)当不希望类被继承时,可以使用final修饰。
2)当不希望父类的某个方法被子类重写时,可以使用final修饰。
3)当不希望某个属性被修改时,可以使用final修饰。
4)当不希望某个局部变量被修改时,可以使用final修饰。
总之,用final修饰的成员就不可被修改了。在不同的成员有具体不同的体现。
final使用注意事项:
1.final修饰的属性又叫常量,一般用XXX_XXX_XXX来命名,全大写。
2.final修饰的属性在定义时必须赋初值,并且以后不能再修改,赋值可以在如下位置之一:
(1)定义时,赋值。如:public static double TAX_RATE=0.08
(2)在构造器中。
(3)在代码块中。
其实就是按照实例一个对象时赋值的顺序。
3.若final修饰的属性是静态属性,则初始化位置只能是
(1)定义时.
(2)在静态代码块中。
静态属性,赋值只有定义和静态代码块中,第一次加载类。
4.final类不能继承,但可以实例化对象。
5.如果类不是final类,但是含有final方法,则该方法虽然不能重写,但却可以继承,子类使用。
6.如果类已经用final修饰了,就没有必要再用final修饰方法了。
因为方法只有继承才有重写之说,不能继承了,何来重写?
7.final常和static搭配使用,效率更高,不会导致类的加载,底层编译器做了优化处理。
8.包装类(Integer,Double,Float,Boolean等都是final),String也是final类。