JAVA核心技术I---JAVA基础知识(单例模式和final关键字)

时间:2021-01-05 20:02:21

一:单例模式

public class single{
    static single Instance=new single();
    String content;
    private single(){
        content="aaa";
    }

    public String getContent(){
        return content;
    }

    public void setContent(String cont){
        this.content=cont;
    }
    
    public static single getInstance(){
        return Instance;
    }
}
public class singleMode{
    public static void main(String[] args){
        single obj1 = single.getInstance();
        System.out.println(obj1.getContent());
        obj1.setContent("ddd");
        single obj2 = single.getInstance();
        System.out.println(obj1.getContent());
        System.out.println(obj2.getContent());
        if(obj1==obj2){
            System.out.println("obj1==obj2");
        }else{
            System.out.println("obj1!=obj2");
        }

    }
}    
aaa
ddd
ddd
obj1==obj2

二:final关键字(同C中const)

Java的final关键字同样可以用来修饰
–类
–方法
–字段
final的类,不能被继承
父类中如果有final的方法,子类中不能改写此方法
类中字段若是用final修饰,不允许修改值
final的变量,不能再次赋值。
– 如果是基本型别的变量,不能修改其值;
– 如果是对象实例,那么不能修改其指针(但是可以修改对象内部的值; 

类:

JAVA核心技术I---JAVA基础知识(单例模式和final关键字)

方法:

JAVA核心技术I---JAVA基础知识(单例模式和final关键字)

字段:

JAVA核心技术I---JAVA基础知识(单例模式和final关键字)

变量基本类型:

JAVA核心技术I---JAVA基础知识(单例模式和final关键字)

变量为对象:不可以修改指针,可以修改对象的值

JAVA核心技术I---JAVA基础知识(单例模式和final关键字) 

总结:

–final类:没有子类继承
–final方法:不能被子类改写
–final变量:基本类型不能修改值,对象类型不能修改

三:static和final问题 

问题一:static代码块和实例化代码块执行时间

以下代码执行结果是

class StaticTest{
  static{  //static静态块
    System.out.print("a ");
  }
  {  //实例化块
    System.out.print("b ");
  }

  public static void main(String[] args) {
    StaticTest st2 = new ChildTest();  //main1
    System.out.print(“ # ”);         //main2
    StaticTest st = new StaticTest();  //main3
  }
}

class ChildTest extends StaticTest{
  static{
    System.out.print("c ");
  }
}
A.a c b # a b

B.a b c # a b c

C.a c b # b

D.a b c # a b
执行main函数时,会首先加载StaticTest(因为main函数就在StaticTest类中)。所以将StaticTest的静态块代码按照顺序执行,输出a .
然后执行main函数第一句话,new一个ChildTest对象,那就需要加载ChildTest类,也把它的所有静态块都执行一遍。
在执行ChildTest的静态块之前,会将执行ChildTest的父类的静态块代码
。注意,任意一个类的一个静态块代码在整个生命周期里面只执行一次。
//main1语句再输出c,然后new ChildTest()将调用父类的构造函数和(非静态的)匿名块,再输出b.
//main2输出#,
//main3将执行StaticTest的所有静态块和(非静态的)匿名块。由于静态块都执行过了,就剩下(非静态的)匿名块,所以输出b。
static代码块随着类的产生开始执行,所以先与实例化代码块。
因为实例化代码块必须在实例化对象时才会执行,之后执行构造方法。
其次:static代码块只执行一次,之后实例化对象不再执行

问题二:final修饰变量

class FinalTest{
  final int num = 1;

  public static void main(String[] args) {
    final FinalTest ft = new FinalTest();//1
    ft.num = 100;//2
    //3
    System.out.println(ft.num);//4
  }
}
A.编译通过,但在//3处加上 ft.num ++; 后编译报错

B.编译通过,但在//3处加上 ft = new FinalTest(); 后编译报错

C.编译不通过,去除//1的 final 后编译通过

D.编译不通过,删除//2 整行后编译通过
因为num是基本类型的变量,且被final了,所以不能修改其值,因此选D