静态方法:又称做类方法,在类加载的时候就存在了,它不依赖于任何实例,可以通过类名来访问。静态方法必须有实现,不能是抽象方法,只能访问所属类的静态成员和静态方法,不能出现 this 和 super 关键字,因为该方法不依赖任何实例就可以访问,而实例变量或者方法必须先创建实例才能访问。
public class A { private int x; //实例变量 private static int y; //静态变量 //main方法本身就是静态方法 public static void main(String[] args) { //int a = x; 报错 int b = y; System.out.println(b); //0 } }静态代码块:仅在类第一次被加载时运行一次的代码块,可用于对静态变量初始化。
public class A { static { System.out.println("hello word!"); } public static void main(String[] args) { A a = new A(); A b = new A(); } } //输出:hello word!静态内部类:非静态内部类必须依赖外部类的实例,而静态类不需要,直接通过外部类名来创建。静态内部类不能访问外部类的非静态的变量和方法。
public class A { public class InnerClass{ } public static class StaticInnerClass { } public static void main(String[] args) { A a = new A(); //非静态内部类的创建,必须依赖外部类的实例 InnerClass innerClass = a.new InnerClass(); //静态内部类的创建 StaticInnerClass staticInnerClass = new A.StaticInnerClass(); } }静态变量声明和静态语句块优先于实例变量声明和普通语句块,静态变量声明和静态语句块的初始化顺序取决于它们在代码中的顺序,最后才是构造函数的初始化。
存在继承情况下的初始化顺序,括号内容的执行顺序取决于在代码的顺序:
父类(静态变量声明、静态语句块)子类(静态变量声明、静态语句块)父类(实例变量声明、普通语句块)父类(构造方法)子类(实例变量声明、普通语句块)子类(构造方法)顺序规则:第一次加载类(还未创建对象)时,从最顶层父类开始执行静态变量声明、静态语句块(执行顺序与代码顺序有关);当真正创建对象时,从最顶层父类开始执行实例变量声明、普通语句块和构造方法(前面两个先执行,执行顺序与代码顺序有关,构造方法最后执行),只有父类成员初始化完毕,才会初始化子类成员。
class Father { { System.out.println("father普通代码块"); } static { System.out.println("father静态代码块"); } public Father() { System.out.println("father构造方法"); } } public class Son extends Father{ { System.out.println("son普通代码块"); } static { System.out.println("son静态代码块"); } public Son() { System.out.println("som构造方法"); } public static void main(String[] args) { new Son(); } } /*输出: father静态代码块 son静态代码块 father普通代码块 father构造方法 son普通代码块 som构造方法 */声明数据为常量,可以是编译时常量,也可以是在运行时被初始化后不能被改变的常量。
对于基本类型,final 使数值不变;对于引用类型,final 使引用不变,也就不能引用其它对象,但是被引用的对象本身是可以修改的。 final int x = 1; //x = 2; //报错,基本类型不能更改 final A a = new A(); a.c = 1; //正常运行,引用变量不能更改引用对象,但可以更改对象数据数据可分为成员变量和局部变量,两种都可以加 final。
final 修饰的成员变量必须显示赋初始值。
不管是静态变量还是实例变量,在分配内存时,会先分配默认值(0,\u0000,false 或 null)。当执行静态代码块或者静态变量声明时可对静态变量显示赋初始值;当执行普通代码块、实例变量声明或者构造器时可对实例变量显示赋初始值。如果变量没有显式赋初始值,变量初始值使用默认值。而被 final 修饰的成员变量使用默认值将毫无意义,所有规定 final 修饰的成员变量必须显示赋初始值。
public class A{ static { //此处代码块比声明执行顺序更早,所以A.a还未赋初始值,为0 //A.b由final修饰,必须有初始值,所以此处先查询声明是否赋初始值,再运行,为10 System.out.println(A.a); //0 System.out.println(A.b); //10 } private static int a = 10; private static final int b = 10; private final int c; //private final int d; //没有赋初始值报错 public A() { c = 10; } public static void main(String[] args) { new A(); } }被 final 修饰的方法不能被子类重写。private 方法被隐式地指定为 final,如果在子类中定义的方法和父类中的一个 private 方法签名相同,不是重写父类方法,而是定义了一个新的方法。
class B { public final void f1() { } private void f2() { } } public class A extends B { public void f1() { //报错 } private void f2() { //正常 } }被 final 修饰的类不能被继承。
final class B { } public class A extends B { //报错 }转载于:https://www.cnblogs.com/zongmin/p/11340334.html
相关资源:JAVA上百实例源码以及开源项目