疯狂java07--面向对象的陷阱

7.1instance运算符的陷阱

instance运算符前面操作数的编译时类型必须是如下三种情况:

*与后面的类型相同

*是后面类型的子类                否则无法通过编译

*是后面类型的父类         

instance运算返回的结果与前一个操作数实际引用的对象的类型有关,如果它实际引用的对象是第二个操作数的实例,或者是第二个操作数的子类,实现类的实例,instance运算的结果返回false,否则返回true。

编译器编译java程序时,无法检查引用变量实际引用对象的类型,只检查该变量编译时的类型。

强制转型

*编译阶段 强制转型要求被转型变量的编译时类型必须是如下三种之一:

与目标类型相同;是目标类型的父类;是目标类型的子类;否则编译错误

*运行阶段 被转型变量所引用对象的实际类型必须是目标类型的实例,或者是目标类型的子类,实现类的实例

否则在运行时将引发ClassCastException异常

一个隐蔽的陷阱:String s=null; s instanceof String------>false它实际并未引用一个真正的String对象。

一个重要的作用:可以保证第一个操作数所引用的对象不是null。不会担心引发ClassCastException或者NullPointerException。

7.2构造器的陷阱

当为构造器声明添加任何返回值类型声明,或者添加void声明该构造器没有返回值时,编译器并不会提示这个构造器有错误,只是系统会把这个所谓的构造器当成普通方法处理。

以下面两种方式创建的java对象无需使用构造器

*使用反序列化的方式恢复java对象,但系统中将会产生两个对象,破坏单例的规则,除非提供readResolve()方法。

*使用clone方法复制java对象,但系统中将会产生两个对象。

7.3持有当前类的实例

一个类的实例持有当前类的其它实例时需要特别小心,因为程序很容易形成递归调用

7.4重载方法的调用问题

java虚拟机在识别方法时具有一定的智能,它可以对调用方法的实参进行向上转型,使之适合被调用方法的需要。

java的重载解析过程分成以下两个阶段:第一阶段JVM将会选取所有可获得并匹配调用的方法或者构造器;

第二阶段决定到底调用哪个方法,此时JVM会在第一阶段所选取的方法或者构造器中再次选取最精确匹配的那一个。

在复杂的情况下,JVM无法断定哪个方法更匹配实际调用,程序将会导致编译错误。

7.5方法重写的陷阱

*父类中定义的private方法不可能被子类重写

*对于不使用访问控制修饰符的方法,它只能被当前类处于同一个包中的其它类访问,其它包中的子类依然无法访问该方法

7.6非静态内部类的陷阱

*非静态内部类inner并没有无参数的构造器,它的构造器需要一个Outer参数。即使系统为非静态内部类提供一个默认的构造器,这个默认的构造器也需要一个外部类形参。

public class Outer {
    public static void main(String[] args) throws Exception {
        new Outer().test();
    }
    private void test() throws Exception{
        System.out.println(new Inner());                                    (1)
//      System.out.println(Inner.class.newInstance());              (2)
    }
    
    public class Inner{
        public String toString(){
            return "inner对象";
        }
    }
}

(1)处的代码程序表面上调用Inner无参数的构造器创建实例,实际上虚拟机底层会将this(代表当前默认的outer对象)作为

参数传入Inner构造器。

(2)行代码效果则不同,程序通过反射指定调用Inner类无参数的构造器,所以引发了运行时异常。

*非静态内部类不能拥有静态成员

*非静态内部类在外部以内派生子类是安全的

*推荐使用静态内部类,因为对于静态内部类来说,它的外部类就相当于它的一个包,因此静态内部类的用法就简单多了,限制也少多了。

声明一个对象,赋值为null,调用普通方法会报空指针异常,但是调用静态方法不会报错。底层会转为类去调用方法,同时也不存在父类引用指向子类对象的情形。静态内部类不能访问外部类的非静态成员,可以访问静态成员。

猜你喜欢

转载自blog.csdn.net/little_____white/article/details/81487568