1. static关键字
当声明一个事物是static时,这个域或方法不会与包含它的那个类的任何对象实例关联在一起。所以,即使未创建某个类的任何对象,也可以调用其static方法或者访问其static域。
一个static字段对每个类只有一份存储空间,而非static字段对每个对象有一个存储空间。
static方法没有this的方法。
2. 引用初始化的位置
1)在定义对象的地方。即总能在构造器被调用之前被初始化
2)在类的构造器中
3)在正要使用这些对象之前,即惰性初始化。在生成对象不值得及不必要每次都生成对象的情况下,这种方式可以减少额外负担。
4)使用实例初始化
public class Soap { private String s; Soap(){ System.out.println("Soap()"); s = "Constructed"; } public String toString() { return s; } } public class Bath{ private String // Initializing at point of definition s1 = "Happy", s2 = "Happy", s3, s4; private Soap castille; private int i; private float toy; public Bath() { System.out.println("Inside Bath()"); s3 = "Joy"; toy = 3.14f; castille = new Soap(); } // Instance initialization: { i = 47;} public String tostring() { if(s4 == null) // Delayed initialization: s4 = "Joy"; return "s1 = " + s1 + "\n" + "s2 = " + s2 + "\n" + "s3 = " + s3 + "\n" + "s4 = " + s4 + "\n" + "i = " + i + "\n" + "toy = " + toy + "\n" + "castille = " + castille + "\n"; } public static void main(String[] args) { Bath b = new Bath(); System.out.println(b); } }
3. 为什么需要RTTI(Run-Time Type Identification)
下图是一个典型的类层次结构图,基类位于顶部,派生类向下扩展。代码只操纵对基类的引用。这样,如果要添加一个新类,来扩展程序,就不会影响原有的代码。shape类中动态绑定了draw()方法,这样客户端程序员使用泛化的shape引用来调用draw(),即多态。shape对象实际执行什么样的代码,是由引用所指向的具体对象Circle、Square或者Triangle而决定的。如果大部分代码尽可能少的了解对象的具体类型,而只与对象家族中的一个通用表示打交道(在该例中是shape)。这样的代码更容易些,易读,易于维护。
abstract class Shape { void draw(){ System.out.println(this + ".draw()"); } abstract public String toString(); }
public class Circle extends Shape{ public String toString(){ return "Circle";} }
public class Square extends Shape{ public String toString(){ return "Square";} }
public class Triangle extends Shape{ public String toString(){ return "Triangle";} }
public class Shapes { public static void main(String[] args) { List<Shape> shapeList = Arrays.asList(new Circle(), new Square(), new Triangle()); for (Shape shape : shapeList) shape.draw(); } }
结果:
Circle.draw()
Square.draw()
Triangle.draw()
4. 抽象类与接口
仅有方法声明而没有方法体的方法称为抽象方法。一个类包含一个或多个抽象方法,该类必须被限定为抽象的,即抽象类。抽象类中允许有普通方法。
接口中的方法都是抽象的。
5. Java泛型为什么使用擦除?
泛型类型只有在静态类型检查期间出现,在此之后,程序中的所有泛型类型都将被擦除,替换为它的非泛型上界。例如,list<T>擦除为list,普通的类型变量在未指定边界的情况下,将被擦除为Object。泛型是Java SE5出现的功能。为了实现迁移兼容性,每个类库和应用程序必须与其他所有的部分是否使用了泛型无关。即它们必须不具备探测其他类库是否使用了泛型的能力。