final:
final修饰类:该类不能被继承;
final修饰方法:该方法不能被继承;
final修饰变量:形式上的常量,不能修改引用。final修饰的基本类型不能被修改,final修饰的引用类型不能修改引用。必须在对象创建之前对其进行赋值:创建时赋值或者在构造函数中进行赋值。
为被final修饰的变量提供setter方法是没有意义的,并且会报错,因为setter是在对象创建后进行修改。
static:
在方法和数据共享区中存在一个区域—静态区,用于存储static修饰的成员变量和方法。因为该区域是共享的,所以如果该区域的值被修改,那么其他对象访问该区域时,得到的值都是被修改后的值,所以也可以使用类名直接调用,因为static修饰后不再输入某个对象而是属于该类。建议使用类名直接调用静态成员。
因为static方法先创建,所以不能访问未创建的非静态成员变量和方法,也不能在static方法中使用this,super去取变量和方法,即使是静态成员变量也不可以,因为在类创建完成之前不能使用这两个关键字。如果要访问静态成员,直接使用它的名字。
静态方法在子类中不存在“重写”(“覆盖”)的说法,用static关键字修饰的方法和变量都属于类本省,即使存在继承关系,子类并没有继承父类的static修饰的变量和方法,所以说即使子类和父类中都有static 方法和变量(即方法名、返回值类型、参数列表和限制符等各方面都相同),他们也是没有任何关系的,他们是相互独立的,他们属于各自类本身的。因此也就不存在多态特性。对于static修饰的变量,当子类和父类中存在同样的static变量时,也是根据“静态引用”而不是“动态引用”来调用相应的变量的。(如何证明子类中的方法不是覆盖的父类中的方法呢?—使用@Override)所以,类中的静态变量和方法是被“静态调用”的而非“动态调用”。
子类可以通过向上转型来访问父类中的静态变量和方法。
匿名对象:
特点:没有变量名,只能使用一次。比如:System.out.println( (new Scanner(System.in)).next() );其中new Scanner(System.in)就是匿名对象。
内部类(类的嵌套):
可以写在类内甚至方法内
成员内部类:向成员变量一样写在其他类中的类,比如:class A{ class B{}},这个B类就是成员内部类。如果想使用B创建实例化对象,那么写法如下:A.B b=new A().new B();
局部内部类:在方法中定义的类,比如:class C{void eat( class D{} )},这个D类就是局部内部类。局部内部类的对象的创建:在该方法(eat())中实例化该内部类(D)的一个对象,并调用该内部类(D)的变量和方法。如:
//Outter.java public class Outter{ public void out(){ class Inner{public void in(){}} Inner i=new Inner(); } } //Test.java main(){ Outter o=new Outter(); o.out();//这样就能使用Inner }
内部类调用外部类的成员变量:
对于一般的成员变量,可以通过this调用,而对于成员内部类而言,如class A{ int i=8; class B{ ...A.this.i...}},这样就可以调用到A的成员变量 i 了(外部类.this.变量名)!
匿名内部类:接口也可以创建匿名内部类(即接口的一个实现类)
package day0331; public class Test { public static void main(String[] args) { //匿名内部类 new Smoking() { @Override public void smoke() { System.out.println("smoking"); } @Override public void eat() { System.out.println("eat banana"); } }.eat(); } } interface Smoking { public abstract void smoke(); public abstract void eat(); }
匿名内部类的局限性在于只能使用一次,如果想取到里面的smoke方法就需要在创建一个匿名内部类,解决办法是:可以通过向上转型来调用方法。
package day0331; public class Test { public static void main(String[] args) { //匿名内部类,局限性在于 Smoking s=new Smoking() { @Override public void smoke() { System.out.println("smoking"); } @Override public void eat() { System.out.println("eat banana"); } }; s.smoke(); s.eat(); } } interface Smoking { public abstract void smoke(); public abstract void eat(); }
声明包的语句必须写在文件有效代码(即忽略注释)的第一行。
导包时要导到java文件所在文件的的那一层。不导包则需要使用 packagename.classname。
代码块:
普通代码块:写在方法中的代码块。
构造代码块:类中使用的代码块,如:class A{ {//构造代码块} }
静态代码块:用static修饰的构造代码块,如: class A{ static{//静态代码块} }。不管类生成多少个对象,静态代码块只执行一次。
类被调用或该类的对象初始化时,存在以下顺序:静态代码块->构造代码块->构造方法
package day0331; //TestCon public class TestCon { static {System.out.println("static block");} {System.out.println("construct block");} public TestCon() { System.out.println("constructor"); } public static void main(String[] args) { TestCon t=new TestCon(); } }
运行结果为:
static block
construct block
constructor