java中子类对象到超类的显式类型转换
考虑以下代码:java中子类对象到超类的显式类型转换,java,casting,type-conversion,Java,Casting,Type Conversion,考虑以下代码: public class Test{ public static void main(String str[]){ B b = new B(); A a1 = (A)b;//Explicit type conversion A a2 = b; } } class A{} class B extends A{} 上述代码中有两行代码: A a1 = (A)b;//Explicit type conversion A a2 = b; 等价物?
public class Test{
public static void main(String str[]){
B b = new B();
A a1 = (A)b;//Explicit type conversion
A a2 = b;
}
}
class A{}
class B extends A{}
上述代码中有两行代码:
A a1 = (A)b;//Explicit type conversion
A a2 = b;
等价物?如果不是,那么两者之间的区别是什么?如果是,那么java中是否有任何场景需要显式地将子类对象转换为超类对象?它们在您的示例中是不等价的 这变得很重要以另一种方式分配,即当对象仍然是类型
B
例如,考虑下面的顺序:
A a = b;// will work
a = (A)b;// will work
B newB = (B)a; //will work
B newB = a; //will fail
两者之间没有区别。事实上,您不需要从子类对象显式地将
类型转换为超类引用
。因此,第一种方法是绝对的冗余
从:-
5.1.5。加宽参考转换
存在从任何引用类型到的加宽引用转换
任何参考类型T,前提是S是T的子类型(§4.10)
扩大引用转换时不需要特殊操作
运行时,因此从不在运行时引发异常。他们
仅仅在于将引用视为在一个文档中具有其他类型
在编译时被证明是正确的方式
只有在引用类型不能明显存储对象的地方,才需要显式类型转换。但当您创建子类的对象并使超类的引用指向该对象时,编译器就不会有问题了。因为它总是可以在运行时处理。引用的显式类型转换(而不是对象)是多余的,一些IDE会建议您放弃它
如果你这样做
A a1 = (A)b;
你还是可以的
B b2 = (B) A;
将引用转换回类型B
注意:对象不会以任何方式更改,并且始终是aB
java中没有需要它的场景
唯一需要向上投射的时间是在方法选择中
void method(Object o) { }
void method(String s) { }
method("hello"); // calls method(String)
method((Object) "hello"); // calls method(Object)
等价物?如果不是,那么两者之间的区别是什么
唯一不同的是,一个是隐式的,而另一个是显式的(这不是必需的),结果是等价的。注意:强制转换根据对象的引用工作,而不是对象本身
java中是否存在需要显式地将子类对象转换为超类对象的场景
Java支持,所以不应该有这样的场景。它们都是相同的。这是一种自动向下排字的情况
a1=(A)b//显式类型转换
A a2=b
在这两种情况下,a1和a2的类型都是A。因此,B的附加特性无论如何都会丢失
如果你做非自动的向上打字,你就会知道区别。考虑下面的例子。
车辆v1=新车()//正确的。向上投射还是隐式投射
车辆v2=新车()
车辆c0=v1;//错误的编译时错误“类型不匹配”
//需要显式或向下转换
汽车c1=(汽车)v1//右侧。向下投射或显式投射。由于1号线的原因,v1对车辆有一定的了解
汽车c2=(汽车)v2//错误的运行时异常ClassCastException,因为v2不了解Car
巴士b1=新宝马()//错误的编译时错误“类型不匹配”
汽车c3=新宝马()//正确的。向上投射还是隐式投射
汽车c4=(宝马)v1;//错误的运行时异常ClassCastexception
对象o=v1//v1只能向上投射到其父级
车c5=(车)v1;//由于1号线的原因,v1可能向下倾斜至轿厢,对于使用过载的方法选择,也需要进行此类类型转换:
package casting;
public class ImplicitCasting {
public static void main(String[] args) {
A a = new A();
B b = new B();
A a1 = new B();
methodA(a); // methodA called
methodA((A)b); // methodA called
methodA(b); // methodB called
}
public static void methodA(A a) {
System.out.println("methodA called");
}
public static void methodA(B b) {
System.out.println("methodB called");
}
}
class A{
}
class B extends A{
}
那么第一句话是多余的?java中没有需要它的场景?对吗?@Ankur。确切地超类引用可以指向其任何子类对象。。这就是多态性的全部要点。最后,我找到了一个可能需要使用它的场景,非常感谢你……在我看来,OP已经清楚地提到了——从子类到超类。这不是一个无效的观点。我有一个场景,我需要获取超类java.util.Map(基本java),在这里我实际获取了它的子类spring.framework.LinkedCaseInsensitiveMap请参见我的帖子: