5

考虑下面的代码:

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中有没有我们需要将子类对象显式转换为超类对象的场景?

4

6 回答 6

10

引用的显式类型转换,而不是对象)是多余的,一些 IDE 会建议您删除它。

如果你这样做

A a1 = (A)b;

你仍然可以做

B b2 = (B) A;

将引用转换回 B 类型。

注意:对象不会以任何方式改变,并且始终是B

java中没有你需要它的场景吗?

唯一需要向上转换的是方法选择。

void method(Object o) { }

void method(String s) { }

method("hello");          // calls method(String)
method((Object) "hello"); // calls method(Object)
于 2012-10-11T16:10:06.000 回答
3

使用重载的方法选择也需要这种类型转换:

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{

}       
于 2012-10-12T07:17:05.857 回答
1

它们在您的示例中不等效。

在其他方式分配中变得很重要,即AB您的对象仍然是类型时B

例如考虑以下顺序:

      A a = b;// will work
      a = (A)b;// will work
      B newB = (B)a; //will work
      B newB = a;  //will fail
于 2012-10-11T16:07:13.097 回答
1

两者没有区别。事实上,您不需要显式地键入 cast from a subclass object to a super class reference。所以,第一种方法是绝对的Redundant

来自JLS - 转换: -

5.1.5。扩大参考转换

如果 S 是 T 的子类型(第 4.10 节),则存在从任何引用类型 S 到任何引用类型 T 的扩展引用转换。

扩大引用转换在运行时从不需要特殊操作,因此从不在运行时抛出异常。它们仅在于以可以在编译时证明正确的方式将引用视为具有某种其他类型。

显式类型转换仅在引用类型可以存储object. 但是,当您创建子类的对象并将超类的引用指向该对象时,编译器就不会出现问题。因为他总是可以在运行时处理。

于 2012-10-11T16:08:35.827 回答
1

相等的?如果不是那么两者有什么区别

唯一不同的是,一个是隐式的,另一个是显式的(这不是必需的),结果是等价的。注意:强制转换是对对象的引用,而不是对象本身。

java中是否存在我们需要将子类对象显式转换为超类对象的场景?

Java 支持Liskov 替换原理,所以不应该有这样的场景。

于 2012-10-11T16:13:26.400 回答
0

他们都是一样的。这是一种自动的向下类型转换的情况。

A a1 = (A)b;//显式类型转换 A a2 = b;

在这两种情况下,a1 和 a2 的类型都是 A。所以 B 的附加特征无论如何都会丢失。

如果您进行非自动的向上类型转换,您将知道区别。考虑以下示例。

车辆 v1 = new Car(); //对 。向上转型或隐式转型

车辆 v2= 新车辆();

车c0 = v1;// 错误的编译时错误 "Type Mismatch" // 需要显式或向下转换 Car c1 = (Car) v1 // 对。向下转换或显式转换。由于第 1 行,v1 具有 Car 的知识

汽车 c2 = (汽车) v2; //错误的运行时异常 ClassCastException 因为 v2 不知道 Car。

总线 b1 = new BMW(); //错误的编译时错误“类型不匹配”

汽车 c3 = new BMW(); //对。向上转型或隐式转型

汽车c4 =(宝马)v1;// 错误的运行时异常 ClassCastexception

对象o = v1;//v1 只能向上转换到它的父 Car c5 = (Car) v1; // 由于第 1 行,v1 可以向下转换为 Car

于 2012-10-11T16:36:26.343 回答