1.final修饰类,方法,变量

  • final修饰局部变量,使用前初始化即可。 修饰成员变量,两种方法初始化,声明的同时初始化或构造方法中初始化
  • 如果final修饰的是基本类型变量,给定值后不能改变。如果是引用类型变量,引用指向的地址不能改变,但是地址中的内容可以变。
public class Student  {
    public final StringBuffer str = new StringBuffer("old");

    public static void main(String[] args) {
        Student stu = new Student();
        stu.str.append(" man");
        //地址没有变,但是内容改变了
        System.out.println(stu.str);// old man
    }
}
  • final修饰的方法不能被重写
  • final修饰的类不能被继承,保护类不被继承修改。一些基础类库被定义为final,例 Integer,Math.....

2.finally

  • finally关键字一般位于try/catch后,在try块运行结束后执行。finally块中的语句总是会在控制转移语句(break、continue、return等)执行之前执行。但是,如果在JVM执行try或者catch块的代码时退出了,那么finally块中的代码也就可能不会被执行到了,就像线程执行的时候被打断或者是直接被杀死这类的情况。
public class Finalll {

    public static void test(){
        try {
            System.out.println("try block");
            System.exit(0);//终止JVM
        } finally {
            System.out.println("finally block");
        }
    }

    public static void main(String[] args) {
        test();//try block
    }
}
  • 当程序执行到retrun时会把返回值放到一个临时栈中,而不是立即返回, 当执行完finally块中的代码后,才会把栈中的值返回。
public class Finalll {

    public static int test(){
        int a = 1;
        try {
            System.out.println("try block");
            return 1;
        } finally {
            System.out.println("finally block");
            //这里并没有使用return,所以只是更新了a的值,并没有更新临时栈的值, 所以返回值还是1
            a = 2;            
        }
    }

    public static void main(String[] args) {
        System.out.println(test());
        //输出结果:
        try block
        finally block
        1
    }
}

3.finalize

  • finalize()是Object中的方法。在gc启动回收对象之前,调用被回收对象的该方法,一个对象的finalize方法只会调用一次。调用了finalize方法,不一定马上回收对象。所以有可能调用了finalize方法,但是对象又不需要被回收了,到了真正回收时,finalize方法已经调用过了,这样就会产生问题。
  • Object中的finalize方法体是空的,主要是提供给子类重写,然后在对象回收之前完成一些操作,比如数据的清理。

4.static

  • static修饰的成员变量不属于对象的数据结构,它属于类,称为类变量/静态变量。无论该类创建了多少对象,静态变量都只有一份,作为全局变量使用。
  • 对于static变量的使用,通过类名直接使用,也可以通过对象调用。
  • 静态成员变量和类信息一起存储在方法区,而不是在堆中。
  • static修饰的方法仅仅和入参有关,直接用类名调用,并没有显示或隐式依赖具体的对象。所以在static修饰的方法中不能使用this,super关键字
public class Stati {

    public void fun(){
        System.out.println("隐式传递了当前对象");
    }
    
    public void test(){
        fun();//有个隐式的this指针
    }

    public static void may(){
        System.out.println("这是一个static修饰的方法");
    }
    
    public static void main(String[] args) {
        //一般的方法都要使用对象调用,fun前面有个隐式的this指针。就是当前调用test方法的对象     
        Stati stati = new Stati();
        stati.test();
         Stati.may();
    }
}
  • 因为static方法在调用时没有具体对象,所以非static成员变量不能直接在static方法中使用。
public class Stati {
    
    private String name;
    
    public static void main(String[] args) {    
       // System.out.println(name);这种会报编译异常
        //如果要使用,必须先创建一个对象        
        Stati stati = new Stati();
        stati.name = "mary";
        System.out.println(stati.name);
    }
    
}
  • static块:属于类的代码块,在类加载期间执行的代码块,只执行一次。如果有多个静态块,jvm会按照顺序依次加载。
public class StaticCode{
        int age;
        // 类的代码块,只执行依次
        static{
            System.out.print("static ");
        }
        //对象的代码块,每创建一个对象执行一次
        {
            System.out.print("55 ");
        }
        
      public  StaticCode(int age){
            this.age=age;
            System.out.print(age+",");
        }
      public void show(){
            // 局部代码块
            {
                int age=30;//就近原则,只在这个范围内有效
            }
            System.out.print("show:"+age+",");
        }

    public static void main(String[] args) {
        StaticCode p1 = new StaticCode(20);
        p1.show();
        StaticCode p2 = new StaticCode(20);
        //static 55 20,show:20,55 20,
    }
}
  • static final修饰的变量称为常量,必须声明的同时初始化,不可改变。
  • 常量会在编译期就被替换
public class StaticFinal{

    public static void main(String[] args) {
        //编译期就会把替换成mary,不会去加载TestF类
        System.out.println(TestF.NAME);
    }

}

class TestF{
    public static final String NAME = "mary";
}

forest
0 声望1 粉丝