为什么Java在检查后不采用该类型?

时间:2018-10-11 21:04:24

标签: java types casting

为什么Java不允许您做注释行?

public static void example(Object other) {
    if (!(other instanceOf Person)) {
        return;
    } else {
        Person p = (Person) other;
        System.out.println(p.name);
        // System.out.println(other.name);
    }   
}

我知道Java是静态类型的,因此必须在编译时知道类型,这就是为什么必须将Object显式转换为Person的原因。但是,是否存在执行与注释行类似的操作会使程序崩溃或危险的情况?逻辑上要输入else子句,类型必须是Person,那么Java为什么不知道呢?

在不安全的情况下,类似情况的例子是什么?

2 个答案:

答案 0 :(得分:4)

没有逻辑原因不能这样做。语言不是按照这种方式设计的。您不能在不破坏向后兼容性的情况下添加此功能,而Java一直将向后兼容性作为优先事项-这是它如此成功的原因之一。

Kotlin允许您执行此操作(它们称为smart cast),并且Kotlin编译为与Java相同的字节码。因此,从技术上讲,Java不能做到这一点,而Java却没有。

也就是说,我们最终可能会获得这样的功能。是just a candidate at the moment。提议的语法类似于:

if (x matches Integer i) {
    // can use i here
}

所以看起来x将保持不变,并且将使用给定类型声明新变量i

答案 1 :(得分:0)

在Java中,每个类都是Object的子级,因此您可以将任何类对象传递/分配给Object,但是Object对类的属性一无所知。在这种情况下,Person类具有name属性,并且您已为其分配了名称,但是Object与Person的name属性无关。

回答您落入else块的问题并不意味着您要传递的对象应该是Person对象,如果Person的子类具有某些可能不为Person知道的属性,也可以是子类课。

    public class TestPolymporphism {
    public static void main(String[] args) {
        Male m = new Male();
        Female f = new Female();
        test(m);
        test(f);
    }

    public static void test(Object obj){
        System.out.println(obj instanceof Person);
        System.out.println(obj instanceof Male);
    }
}

class Person {
    String name;
}

class Male extends Person {

}

class Female extends Person {

}