有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么对派生类的强制转换必须是显式的而不是隐式的

Object o = new Student(); // Implicit casting

我非常理解这段代码,我理解的是引用变量“o”指的是“Object”类型的数据,我们可以看到Student是从“Object”扩展而来的,这意味着它指的是Student的一个实例。 如果我写了以下代码:

Object x = o;

这将把o中的值赋给x,这意味着如果我们沿着x的方向走,我们将到达上面的学生对象

我的问题是,为什么我不能编写以下代码

Student x = o;

“o”指的是“object”类型的对象,该对象将其地址(内存中)分配到“o”中,为什么我们不能将保存在o中的值分配到x中呢


共 (6) 个答案

  1. # 1 楼答案

    您可以将Student的实例分配给声明为Object类型的变量,因为每个Student都是Object的一种(或专门化)。由于不是每个对象都是学生,编译器在将它只知道是对象实例的东西分配给对象的任何专门化(例如学生)时会犹豫。因此,您可以毫不费力地隐式地将一个更一般类型的实例变量赋值给它,但在相反的方向上,编译器希望确保您的意思是这样做,所以您显式地向下转换

    Student x = (Student)o;
    

    这就是静态类型语言的本质

  2. # 2 楼答案

    Object o = new Student();  //upcasting - Implicit cast
    Student x = (Student) o;   //downcasting -Explicit cast
    

    向上转换:我们正在缩小引用转换的范围(向上移动继承层次结构)。由于Student IS-A对象,因此不需要显式强制转换

    向下播放:我们正在扩大引用转换(向下移动继承层次结构)。因为对象可以是任何东西,所以我们必须使用显式强制转换将其强制转换给学生

  3. # 3 楼答案

    Java只允许隐式向上转换,不允许隐式向下转换

    Java中的向上转换也称为加宽转换,向下转换称为缩小转换

    对象可以隐式或显式转换为超类型。在本例中,ObjectStudent的超类型

    Object o = new Student();
    Object x = o; // implicit works
    Object x = (Object) o; // explicit works
    

    对象不能隐式转换为子类型,必须显式转换。在本例中,StudentObject的一个子类型

    Object o = new Student();
    // Student x = o; // implicit doesn't work
    Student x = (Student) o; // explicit works
    

    Explicit and Implicit Type Casting - Herong Yang

    5.1.5. Widening Reference Conversion - Java docs

    5.1.6. Narrowing Reference Conversion - Java docs

  4. # 4 楼答案

    Object o;
    
    if (Math.random < 0.5) {
      o = new Student();
    } else {
      o = new Dog();
    }
    

    显然,你不能有Student x = o;

    除非那条狗也是学生,但那是另一回事

  5. # 5 楼答案

    您需要显式地将其强制转换为学生

    Student x = (Student) o;
    

    这是因为编译器不知道这是否正确,所以您需要将其转换为“我相信这会起作用。请相信我”

  6. # 6 楼答案

    这里没有演员表演

    正如您所说,ObjectStudent的基类
    这意味着Student的每个实例也是一个Object,我们可以始终将其视为一个实例

    Object o = new Student(); // A Student is an Object
    

    然而,相反的关系并不成立——并非所有的Object实例都是Student

    Student分配给o后,编译器将无法获得它实际上是^{aStudent的信息
    这些信息在运行时可用-您可以说o instanceof Student,它将 是真的-但是编译器不知道这一点