一、final
final关键字有最终的,不可修改的含义,final可以用来修饰变量,方法,类。
如果修饰变量,那么这个变量就会变为常量。一般语法:
[访问修饰] final 数据类型 常量名 = 值;
常量在声明时必须初始化,声明之后不能对其进行二次赋值,其后任何的赋值语句都会出现编译错误。
如果修饰方法,意味着该方法不能被子类覆盖,但可以被重载。因为这和abstract有冲突,所以final不能和abstract一起出现。
声明格式:
[访问权限] final 返回值类型 方法名(参数列表){ .... }
如果修饰类,那么则说明该类无法被继承。
声明格式:
[访问权限] final class 类名{ 成员列表 }
Java中有一个最常用的final类,java.lang.String
二、static
针对一个类所有对象的共性属性,Java采用static成员同一调用。
静态方法属于类而不属于某一个对象。其在加载类时就已经被虚拟机初始化,此时不存在任何对象的概念,所以没有办法隐式传递参数this,自然也就不能再static中使用this来调用对象本身了。但这并不意味这不能调用非静态区域,我们可以通过现实参数传递来做到这一点。
被static修饰的成员或者方法,可以直接使用类名进行调用,因为static修饰的成员属于类,而不是只属于单独的某一个对象。
静态成员变量的作用域只在类内部,但其生命周期却贯穿整个生命周期。
可以使用实例化的对象去调用静态成员,也可以直接使用类名来调用静态成员。
static在变量或者方法之前,表明他们是属于类的,称为类方法(静态方法)或者变量(静态变量)。如果没有static修饰,则是实例方法或者普通成员变量。
内存分析:
和类的其他成员属性或者方法不同,static修饰的方法或成员属性并不存放在对象对应的堆内存中,而是存放在方法区中,每个对象的相应static共享同一段内存。
JDK1.5之后引入了“static import”机制,示例:
import static java.lang.Math.*
表示导入Math类中的所有静态成员,之后调用这个类中的方法时,只需要直接使用方法名就可以了,而不是使用Math.方法名。
如果出现导入的类中有两个同名的方法,那么会有两种情况:
1.如果两个语句都是精确导入的形式,或者都是按需导入的形式,那么会造成编译错误。
2.如果一个语句采用精确导入的形式,一个采用通配符(*)按需导入的形式,那么采用精确导入的形式的一个有效。
如果是一个方法一个属性的重名,则不会受到冲突。
之所以在非静态里可以使用this指针来指向当前类对象的引用,是因为非静态方法参数传递时,有一个隐式参数this,示例:
1 Object o = new Object();
2 o.toString();
3
4 // 实际上是 o.toString(Object this);
三、包装类
Java语言中有8个基本数据类型,对应的有8个类,这8个类称为包装类。
包装类的出现是为了能够把这八种基本数据类型的变量转换成转换成引用类型,从而使用类中的方法,进行更多的操作:
装箱:基本数据类型转换成引用数据类型,称为装箱。 例如:int 类型转换成 Integer 类型。
拆箱:引用数据类型转换成基本数据类型,称为拆箱。 例如:Integer 类型转换成 int 类型。
JDK1.5之后,装箱和拆箱可以自动进行。
四、内部类
内部类是Java独有的一种语法结构,即在一个类的内部定义一个类,此时,内部类就成为外部类的成员,访问权限遵循类成员的访问权限机制,内部类可以使public、protected、缺省和private。
内部类可以很方便的访问外部类中的成员。
内部类是一个编译时的概念,一旦编译成功后,他就与外部类属于两个完全不同的类。
由于内部类本质上是一个独立的类,因此在内部类中直接使用this,其指代的是内部类自身的引用,如果想要引用外部类的对象,则应该使用外部类类名.this的方式
对于一个名为OuterClass的外围类和一个名为InnerClass的内部类,在编译成功后,会出现这样两个class文件:OuterClass.class和OuterClass$InnerClass.class
Java中内部类主要分为成员内部类、局部内部类、匿名内部类、静态内部类。
1.成员内部类
第一:成员内部类中不能使用static的变量和方法。
第二:成员内部类是依附于外部类的,所以只有创建了外部类才能够创建内部类。
2.静态内部类
第一:它的创建是不需要依赖于外部类的。
第二:他不能使用外部类的非static成员变量和方法。
第三:和成员内部类不同,static内部类可以声明和使用static成员。
3.局部内部类
局部内部类存在于方法中。为了解决某些问题,而且又不想被该方法外的作用域访问这个类,所以出现了局部内部类。
局部内部类对外部类变量的访问存在以下规则(但是JDK1.8以后取消了这一规则):
局部内部类可以直接操作外部类的成员变量,但是对于方法中的临时变量,(包括方法中的参数,要求是final常量才能操作)
4.匿名内部类(省去类名,而不是方法的引用名)
第一:匿名内部类必须继承一个父类或实现一个接口。
第二:如果一个内部类只需要构建一个单一的对象,那么这个类其实并不需要额外去一个类名,对于不存在名字的内部类我们称之为匿名内部类。
第三:匿名内部类中没有构造方法。
第四:匿名内部类想要初始化,可以交由类初始化代码块或者实例化代码块来完成。
第五:匿名内部类对类成员、方法临时变量的访问规则和具备名字的内部类保持一致。
声明格式:
[访问权限] [修饰符] 父类名/接口名 引用名 = new Teacher(){
// 匿名内部类成员
};