Java 接口类对象、强制转换、异常
我看到了这个代码:Java 接口类对象、强制转换、异常,java,object,interface,casting,Java,Object,Interface,Casting,我看到了这个代码: interface I{} class A implements I{} class B extends A{} class C extends B{} class ABC { public static void main(String args[]) { A a=new A(); B b=new B(); a=(B)(I)b; //Line 1 b=(B)(I
interface I{}
class A implements I{}
class B extends A{}
class C extends B{}
class ABC
{
public static void main(String args[])
{
A a=new A();
B b=new B();
a=(B)(I)b; //Line 1
b=(B)(I)a; //Line 2
a=(I)b; //Line 3
I i=(C)a; //Line 4
}
}
试图找出
有人能给我解释一下这三个概念吗?在java中,类似于类的接口是一种类型。在您的示例中,类A的对象属于类型A和类型I。类B的对象属于类型B、类型(子类型)A和类型I。类C的对象属于类型C、类型(子类型)B、类型(子类型)A和类型I。如前所述,对象属于两种类型的类型(两种类型之间没有链接,即A和I是独立的类型)以及它们各自超类的子类型 根据Leskov的替换原理,可以用子类型(子类)代替超类型(超类)。要进行说明,请查看下面的代码片段: 公共类继承测试{
public interface I{}
public class A implements I{}
public class B extends A{}
public class C extends B{}
public class D implements I{}
public class E{}
public void method(){
A a=new A();
B b=new B();
C c=new C();
D d=new D();
I i=null;
i=a;i=b;i=c;
a=b;
b=c;
a=c;
a=(A)i;//a=i does not work, A and I are two different types
i=d;
a=(A)i;//ClassCastException at runtime, D is not an A
E e=new E();
//a=(A)e; - this generates a compile time error
}//method closing
}//下课
强制转换是必要的,因为根据代码,一切照旧,但一切都不照旧,即我可以有一个实现了i但与a继承层次结构完全无关的类D。通常,当您必须在两个未连接的类型之间转换时,需要强制转换
注意:我已经编辑了代码以包含另一个D类
注意:我对代码进行了编辑,为第三行添加了另一个类E,导致编译时失败的不是强制转换-而是试图将编译时类型
I
的值分配给a
类型的变量……在第2行,您得到了一个不是B
的对象,您试图将其分配给类型为B
的变量。为什么这在运行时是可以的?因为我们已经将其铸造到B@davidI,但您不知道铸造是什么。这不是一种将对象从一个类转换为另一个类的方法。它不会改变底层对象。最后两行是指a=(D)i吗@Ironlca@Gpar,我稍微编辑了代码,我想强调的是类型D的对象,虽然类型I的对象不是类型A的对象(因为A和I是两个独立的类型)。在编译时,这一行不会在运行时产生任何错误。我可能会有点愚蠢地问这个问题。对不起,为什么编译器不能看到I=d,d不能是A类型,然后显示编译时错误而不是运行时异常?作为a=(a)d;是一个编译时错误@Ironluca@Gpar,这是一个自然的问题。首先,类A的对象属于类型I。其次,Java是一种强类型语言,它检查对象的类型分配,现在,这种类型检查对可用的编译时信息进行操作,例如变量(符号)I属于类型I,变量A属于类型A,A的对象也属于类型I,因此允许强制转换,编译器通常无法确定实际分配给i的是什么,这是一个运行时问题,因此它不会在a=(a)i上生成任何错误。。。续。最后一行(注释),编译时知道a和e不是同一类型,因此生成编译时错误,在这种情况下不需要运行时信息来确定是否存在错误。这也是a=i赋值不起作用的原因,它们是两种不同的类型,需要强制转换。因此,编译器会突出显示任何可能由编译时信息确定的错误,并且需要运行时信息,编译器不会生成错误