Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 什么使对象赋值与另一个类兼容?_Java_Inheritance_Casting - Fatal编程技术网

Java 什么使对象赋值与另一个类兼容?

Java 什么使对象赋值与另一个类兼容?,java,inheritance,casting,Java,Inheritance,Casting,我想知道是什么特别允许一个类的对象转换为另一个类。查看Class.isInstance(Object obj),它表明一个对象必须与另一个类“赋值兼容”,才能强制转换到该类。但什么构成“任务兼容” 我正在试图弄清楚以下内容是如何返回ClassCastException的: public class A { multiple private attributes No constructor multiple public methods } public class B

我想知道是什么特别允许一个类的对象转换为另一个类。查看Class.isInstance(Object obj),它表明一个对象必须与另一个类“赋值兼容”,才能强制转换到该类。但什么构成“任务兼容”

我正在试图弄清楚以下内容是如何返回ClassCastException的:

public class A
{
    multiple private attributes
    No constructor
    multiple public methods
}

public class B extends A
{
    blank default constructor
    2 additional private attributes
    4 additional public getter / setter methods for these attributes
}
线路

B b = (B)variable.getA()  // where getA() returned an instance of class A
返回ClassCastException a不能转换为B。我知道从父类转换为子类是个坏主意。我没有编写有问题的代码,我只是在生产支持能力方面进行研究

类B是代码库中唯一从A扩展而来的类。因此getA()的结果不是A(比如C)的另一个子类转换为A的对象


那么,在这个实例中,为什么Java不能将类A的对象强制转换为看似兼容的类B呢?

抛出,表示代码试图将对象强制转换为它不是实例的子类。例如,以下代码生成一个
ClassCastException

 Object x = new Integer(0);
 System.out.println((String)x);

更多信息和信息。

考虑以下两种情况:

A a = new B();
B b = (B)a;    <--  Ok.

A a = new A();
B b = (B)a;    <--  ClassCastException
A A=新B();

B=(B)a 如果我们用有意义的名字来代替A和B,帮助我们思考这个问题,那么答案就会更清楚。如果A变成哺乳动物,B变成狗,那么我们可以合理地说所有的狗都是哺乳动物,但我们不能说所有的哺乳动物都是狗。即使它们表面上具有相同的属性,也不能保证所有哺乳动物都能履行作为狗的契约,编译器也不应该试图这样假设。

的javadoc给出了分配兼容的定义:

具体地说,如果该类对象表示一个已声明的类,则如果指定的对象参数是所表示类(或其任何子类)的实例,则该方法返回true;否则返回false。如果此类对象表示数组类,则如果指定的对象参数可以通过标识转换或扩展引用转换转换为数组类的对象,则此方法返回true;否则返回false如果此类对象表示接口,则如果指定对象参数的类或任何超类实现此接口,则此方法返回true;否则返回false。如果该类对象表示基元类型,则该方法返回false


基本上,如果类型A扩展或实现类型B,您可以将类型A的对象分配给类型B的变量。

只是想添加官方规范以支持 “如果类型A扩展或实现类型B,则可以将类型A的对象分配给类型B的变量”:

JLS对分配兼容性的定义如下:

如果表达式的类型可以通过赋值转换转换为变量的类型,我们说表达式(或其值)可以赋值给变量,或者,等价地,表达式的类型与变量的类型是赋值兼容的

术语“分配转换”仅定义为应用“分配上下文”章节中给出的列表中的适当转换:

术语“转换”也用于描述特定上下文中允许的任何转换,但不具体。例如,我们说作为局部变量初始值设定项的表达式要进行“赋值转换”,这意味着将根据赋值上下文的规则为该表达式隐式选择特定的转换

与引用类型最相关的是

如果S是T的子类型(§4.10),则存在从任何参考类型S到任何参考类型T的扩展参考转换

子类型包括实现的接口(请参见)


数字类型和泛型类型还有其他规则,但它们与问题中给出的示例无关。

让Java相信Java不需要猜测。它知道对象的类型。如果它是具体类型
A
的实例,那么它就不是
B
。谢谢Sotirios。我重新措辞了最后一句,希望能总结得更好一些。A和B都有相同的属性和方法,B有两个额外的属性和方法。因此,您可能会认为可以使用类A对象的属性创建类B对象,并使用类B的默认值作为额外属性。这个问题旨在帮助我理解为什么它们看起来是兼容的,但实际上不是。你对“兼容”的定义是什么。  A和B在视图中看起来与A相似,但B有一些额外的东西。A的实例无法作为B工作,因为该实例没有只有B具有的“samething extra”。换句话说,B可以被强制转换为A,因为正如您在代码中声明的那样,“B扩展了A”。当我说兼容时,我的意思是能够被强制转换为。你是说A不能被转换成B,因为B有两个额外的属性?我以为这些将被设置为null或它们的默认值?在我的例子中,B的类定义对这两个附加属性都有默认值。这并没有解决核心问题“是什么使一个对象与另一个类‘赋值兼容’”,而且这个例子也不相关,因为这两个类是相似的,而不是由不同的类型组成,比如整数/字符串。但是编译器不允许这样做,因为有可能哺乳动物能够履行作为狗的契约吗?对我来说,这很有可能。谢谢里卡多。这就是我一直在寻找的答案。这段代码a)编译b)似乎在99%的情况下都能正常工作,这似乎很奇怪。所以我认为它可能更复杂一些,比如匹配方法和属性