java向下造型,在Java中向下转换

在运行时有可能发生下行的情况下允许下行:

Object o = getSomeObject(), String s = (String) o; // this is allowed because o could reference a String

在某些情况下,这将不会成功:

Object o = new Object(); String s = (String) o; // this will fail at runtime, because o doesn't reference a String

在其他方面将起作用:

Object o = "a String"; String s = (String) o; // this will work, since o references a String

请注意,一些演员在编译时将被禁止,因为他们永远不会成功:

Integer i = getSomeInteger(); String s = (String) i; // the compiler will not allow this, since i can never reference a String.

用你的例子,你可以做到:

public void doit(A a) { if(a instanceof B) { // needs to cast to B to access draw2 which isn't present in A // note that this is probably not a good OO-design, but that would // be out-of-scope for this discussion :) ((B)a).draw2(); } a.draw(); }

我相信这适用于所有静态types的语言:

String s = "some string"; Object o = s; // ok String x = o; // gives compile-time error, o is not neccessarily a string String x = (String)o; // ok compile-time, but might give a runtime exception if o is not infact a String

types转换有效地表示:假设这是对类的引用,并将其用于此类。 现在,让我们说o 实际上是一个整数,假设这是一个string没有意义,并会给出意想不到的结果,因此需要有一个运行时检查和一个exception来通知运行时环境有什么错误。

在实际的应用中,你可以编写一个更通用的类的代码,但是如果你知道它是什么子类,就把它转换成一个子类。 一个典型的例子是覆盖Object.equals()。 假设我们有一个汽车类:

@Override boolean equals(Object o) { if(!(o instanceof Car)) return false; Car other = (Car)o; // compare this to other and return }

我们都可以看到你提供的代码在运行时不起作用。 那是因为我们知道new A()expression式永远不可能是typesB的对象。

但是这不是编译器看到的。 当编译器检查是否允许转换时,它只会看到:

variable_of_type_B = (B)expression_of_type_A;

正如其他人所表明的那样,这种演员是完全合法的。 右边的expression式可以很好地评估Btypes的对象。 编译器看到A和B有一个子types关系,所以在代码的“expression式”视图中,转换可能会起作用。

编译器在确切知道对象typesexpression_of_type_A真正含义时,不会考虑特殊情况。 它只是将静态types看作A并认为dynamictypes可以是A或A任何后代,包括B

在这种情况下,为什么Java在运行时无法执行时允许向下转换?

我相信这是因为在编译时编译器没有办法知道转换是否成功。 举个例子,很容易看到演员阵容会失败,但还有一些时候演员阵容不太清楚。

例如,假设typesB,C和D全部扩展typesA,然后public A getSomeA()方法public A getSomeA()根据随机生成的数字返回B,C或D的实例。 编译器无法知道该方法将返回哪个确切的运行时types,所以如果以后将结果转换为B ,则无法知道转换是否成功(或失败)。 因此,编译器必须假定强制转换将成功。

@原创海报 – 请参阅内嵌评论。

public class demo { public static void main(String a[]) { B b = (B) new A(); // compiles with the cast, but runtime exception - java.lang.ClassCastException //- A subclass variable cannot hold a reference to a superclass variable. so, the above statement will not work. //For downcast, what you need is a superclass ref containing a subclass object. A superClassRef = new B();//just for the sake of illustration B subClassRef = (B)superClassRef; // Valid downcast. } } class A { public void draw() { System.out.println("1"); } public void draw1() { System.out.println("2"); } } class B extends A { public void draw() { System.out.println("3"); } public void draw2() { System.out.println("4"); } }

当我们正在处理一个上传的对象时,Downcast就起作用了。 上溯造型:

int intValue = 10; Object objValue = (Object) intvalue;

所以现在这个objValuevariables总是可以被转换为int因为被转换的对象是一个Integer ,

int oldIntValue = (Integer) objValue; // can be done

但是因为objValue是一个Object,所以不能转换为String因为int不能转换为String 。

Downcasting在下面的代码片段中非常有用,我总是使用它。 从而certificate向下转换是有用的。

private static String printAll(LinkedList c) { Object arr[]=c.toArray(); String list_string=""; for(int i=0;i

我将string存储在链接列表中。 当我检索链接列表的元素时,返回对象。 要访问元素作为string(或任何其他类对象),向下转换帮助我。

Java允许我们编译相当于我们做错事情的代码。 如果人类犯了一个错误,那么在运行时就会被捕获。

考虑下面的例子

public class ClastingDemo { /** * @param args */ public static void main(String[] args) { AOne obj = new Bone(); ((Bone) obj).method2(); } } class AOne { public void method1() { System.out.println("this is superclass"); } } class Bone extends AOne { public void method2() { System.out.println("this is subclass"); } }

这里我们创buildBone子类的对象,并将其分配给超类AOne引用,现在超类引用在编译期间不知道子类Bone中的方法method2。因此,我们需要将这个超类的引用向下转换为子类引用,如所得到的参考可以知道子类即骨中的方法的存在

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值