java基础第九篇之final和内部类等

final关键字:final:最终,终极

 

final:作用:修饰类,变量,方法、成员变量的访问

1.final修饰变量:

    final修饰局部变量:

把这个局部变量 变成一个厂里,这个厂里只能被赋值一次

final修饰成员变量:

要求这个成员变量 在创建对象之前必须初始化

所以final修饰的成员变量 第一直觉赋值 第二构造方法赋值

但是也只能赋值一次

 

2.final修饰的类:(太监类) ,不能被子类继承(String)

    final修饰的方法:(子类不能重写)

 

静态代码块:通常写到成员位置

 *   static {代码}

静态成员变量优先于静态代码块执行,优先于构造方法执行,优先于main方法执行

 *

 * 特点1.在同一个类中 静态代码块是优先于构造方法执行,静态代码块优先于main方法

 * 而且只会执行一次,第一次使用到(可能是创建对象,也可能是调用对象的静态成员)这个类就是会执行

 

 在jdk1.7版本中局部内部类访问局部变量必须用final修饰.

因为当调用这个方法时,局部变量如果没有用final修饰,他的生命周期和方法的生命周期是一样的,当方法弹栈,这个局部变量也会消失,那么如果局部内部类对象还没有马上消失

想用这个局部变量,就没有了,如果用final修饰会在类的加载的时候进入常量池,即使方法弹栈,常量池的常量还在,也可以继续使用.

 

但是在jdk1.8取消了这个事情,所以我认为是个bug;

 

Student s = new Student()

 

做了哪些事情

1.Student.class加载进内存.

2.声明一个Student类型引用.

3.在堆内存创建对象.

4.给对象中属性默认初始化值

5.属性进行显示初始化

6.构造方法进栈,对对象中的属性赋值,构造方法弹栈

7.将对象的地址值赋值给s

 

 

class Fu {

static {

syso(“A”);

}

 

{

syso(“B”)

}

 

public Fu() {

syso(“C”)

}

 

 

}

class Zi extends Fu{

static {

syso(“AA”);

}

 

{

syso(“BB”)

}

 

public Zu() {

syso(“CC”)

}

 

}

class Test {

main {

Zi z = new Zi();

}

}

 

1.Jvm调用了main方法,main进栈

2.遇到Zi z = new Zi();会将Fu.class和zi.class分别加载进内存,再创建对象,当Fu.class加载进内存

父类的静态代码块会随着u.class一起加载,当Zi.class加载进内存,子类的静态代码块会随着Zi.class一起加载

第一输出父类静态,第二输出子类静态

3.走Zi类的构造方法,因为java中分层初始化,先初始化父类,在初始化子类,所有先走父类构造,但是在执行

父类构造时,发现父类有构造代码块,构造代码块就优先于构造方法执行,所以abstract不能和private,

第三个输出构造代码块Fu,第四个构造方法Fu

4.Fu类初始化结束,子类进行初始化,第五个输出构造代码块zI,构造方法Zi

 

 

1.包:就是文件夹,管理.java文件的,管理.class文件。

 

2.包:以”.”分割每一个单纯,每一个单纯代表一个文件夹

实际开发中:包的写法一般是公司的域名倒过来写

 

3.全限定类名: 包名.类名

    例如:cn.baidu.demo03.PackageDemo

 

4.导包的关键字 import

4.1先导包 import java.util.Scanner;

4.2Scanner sc = new Scanner(System.in);

 

在java中有四种权限修饰符:

 

权限从大到小 以此为:

    public(公共的) protected(受保护的) default(默认的) private(私有的)

 

1.public修饰 在哪里都可以用(在本包中或者在其他包中都可以用)

2.private修饰 只能在本包中的本类中可以使用

 

protected(受保护的) default(默认的)

 

共同点:这两个修饰的成员只能在本包中使用

不同点:protected修饰的成员的,不同包的子类中也可以使用

 

内部类:

    在第一个类的内部 再定义第二个类,那么第二个类称为内部类 第一个类称为外部类

 

根据内部类定义的位置不同

那么可以分成:

 

局部内部类:定义类在方法的里面,开发从来不用.

成员内部类:定义类的外部类的成员位置

创建成员内部类对象的格式:

外部类名.内部类名 变量名 = new 外部类().new 内部类();

 

成员内部类的作用:

成员内部类可以无条件访问外部类的任何成员.

 

匿名内部类: 一种语法格式,用来快速创建抽象类的子类或者接口的实现类对象

 *

 * 1.创建一个抽象类

 * 2.用一个子类继承抽象类

 * 3.创建子类的对象

 

  //dd.eat();

//匿名内部类的第一种写法

new Animal(){

@Override

public void eat() {

// TODO Auto-generated method stub

System.out.println(“未知的动物在吃shi”);

}

};

//匿名内部类的第二种格式

Animal an = new Animal(){

@Override

public void eat() {

System.out.println(“未知的动物在吃shi”);

}

};

//匿名内部类的第三种格式

new Animal(){

@Override

public void eat() {

System.out.println(“未知的动物在吃粑粑”);

}

}.eat();

//用匿名内部类创建接口的实现类对象

NYInterface nvyou = new NYInterface(){

 

@Override

public void cook() {

// TODO Auto-generated method stub

System.out.println(“未知的女友在给你做饭”);

}

 

 

};

 

nvyou.cook();

 

1.类可以作为方法的参数和返回值,我们需要是这个类的对象

 *

 * 2.抽象类也可以作为方法的参数和返回值,我们需要的抽象类子类的对象

 *

 * 3.接口也可以作为方法的参数和返回值,我们需要的接口的实现类对象

 

 2. static 方法与普通方法有什么区别?

static 方法在内存中只有一份,普通方法在每个被调用中维持一份拷贝,

static方法属于类方法随着类的加载而加载!普通方法属于对象随着对象

的创建而存在随着对象的消失而消失。

 

3.是否可以在static环境中访问非static变量?

答:static变量在java中是属于类的,它在所有实例中的值都是一样的。

当java虚拟机载入的时候会对static变量进行初始化。如果你的代码尝

试不用实例来访问非static的变量,编译器会报错,因为这些变量还没

有被创建出来,还没有和任何实例关联上。

 

4.使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?

使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的。

请说出作用域public,private,protected,以及不写时的区别?

这四个作用域的可见范围如下表所示。

说明:如果在修饰的元素上面没有写任何访问修饰符,则表示空的(default)。

作用域 当前类同一package子孙类其他package

public √ √ √ √

protected √ √ √ ×

default√ √ × ×

private √ × × ×

 

创建内部类的时候先创建了外部类对象然后才创建内部类对象

 

抽象类要让子类继承并重写抽象方法,使用private修饰便不能被继承和重写,使用final修饰也不能被重写,

使用static修饰,可以类名直接调用方法,但抽象方法没有主体调用无意义,所以abstract不能和private,

final,static共用

 

修饰类只能使用public、final、abstract关键字,A、B错;

(2)abstract不能与private、static、final共用,C、D错;

(3)接口中只有常量和抽象方法,常量修饰符为public static  final,F错。

本题主要考查对不同修饰符的理解以及它们之间互相组合来使用的注意事项。

 

 

abstract不能和那些关键字共存:

 

1:private:因为一个abstract方法需要被重写,所以不能修饰为private;

 

2:final:因为一个abstract方法需要被重写.被final修饰的方法不能被重写的,所以不能同final共存;

 

3:static:因为一个abstract方法没有方法体.静态方法需要对方法体执行内容分配空间,所以不能同static共存;

(abstract是没有实现的,不能产生对象,而是static是属于类的,类本身是已经存在的对象)

 

4:synchronized:是同步的,然而同步需要具体的操作才能同步,但,abstract是只有声明没有实现的(既,使用synchronized关键字的是需要有具体的实现

同步的操作的,但是使用abstract时只有声明而没有实现的,这样就产生了冲突)

 

5:native:他们本身的定义就是冲突的,native声明的方法时移交本地操作系统实现的,而abstract是移交子类对象实现的,同时修饰的话,导致不知道谁实现声明的方法.

 

为什么构造方法不能被继承?

    可以这样理解构造器,构造器就是用来创造对象诞生的。说的形象的就是,你爸和你妈有一个构造器,才会造成你的出现。你爷和你奶也有个构造器,才会造成你爸的出现

。 要是构造器能继承的话,那你爸和你妈可以没有自己的构造器。那这样你就可以直接从你爷爷和你奶奶的构造器出来了。这不就造成你和你爸,的诞生没有次序了嘛?

ClassCastException:  类型转换错误

点赞