Java编译器和接口转换
我正在研究Java中的强制转换,特别是使用接口进行强制转换。假设我有一个定义方法跳转的接口Java编译器和接口转换,java,interface,casting,Java,Interface,Casting,我正在研究Java中的强制转换,特别是使用接口进行强制转换。假设我有一个定义方法跳转的接口I,即: interface I{ public void jump(); } 另外,假设我还有3个类,A,B和CA实现IB没有。但是,C扩展了B并实现了I class A implements I { public void jump(){ System.out.print("A is jumping"); } } class B { } class C extends
I
,即:
interface I{
public void jump();
}
另外,假设我还有3个类,A
,B
和C
<代码>A实现I
<代码>B没有。但是,C
扩展了B
并实现了I
class A implements I {
public void jump(){
System.out.print("A is jumping");
}
}
class B { }
class C extends B implements I {
public void jump(){
System.out.print("C is jumping");
}
}
现在,如果我尝试将A
类型的对象指定给I
,则没有问题,甚至不需要强制转换。即:
I i = new A();
没关系,不用投了
这大概是因为编译器知道A实现了I。此外,如果我尝试这样做:
A mya = new A();
I i = mya;
没有问题,即使mya
可能引用了a
的子类。但这没关系,因为编译器知道A
的每个子类都必须隐式实现jump
方法,因此接口A
但是,如果我尝试将B
类型的对象分配给I
,那么我确实需要强制转换。e、 g
B myb = new B();
I i = (I)myb;
这大概是因为编译器知道B
没有实现I
。但是,由于B
可以引用实现I
的子类,因此您可以强制转换到I
。到现在为止,一直都还不错。
现在我的问题是:如果我想将引用C
(实现I
)类型的对象的B
类型的对象分配给I
,那么我们需要强制转换。为什么呢?例如
B b = new C();
I myI = b; //Won't compile this needs a cast
I myI = (C)b; // This will compile
myI = (I)b; // This will also compile
为什么编译器不明白B
指的是实现I的C
大概是因为B
可以引用一个B
,它实际上没有实现I
,但是为什么编译器不知道呢?大概编译器仅限于每行上可用的信息?它无法运行您的程序并看到b
实际上指向aC
?如果这是正确的,有人能告诉我一些关于Java编译器如何工作以及它们的局限性的文献吗
这大概是因为编译器知道B不实现I,但是因为B可以引用实现I的子类,所以您可以强制转换为I
不完全是。编译器将允许您根据需要强制转换B。这并不意味着您在运行时不会得到ClassCastException
。(这次代码可以正常工作,但编译器不会阻止您进行错误的强制转换。)
为什么编译器不明白B指的是实现I的C?这大概是因为B可以引用一个B,而B实际上并没有实现I,但为什么编译器不知道呢
因为您在声明bb=newc()时告诉它将对象视为aB
代码>
大概编译器仅限于每行上可用的信息?它不能在你的程序中运行,并看到b实际上指向c
它可以访问代码的其余部分。它只是在做你告诉它要做的事情:把b
当作类b
的对象。在这种特殊情况下,编译器有能力确定b实际上是指C的对象。然而,语言创建者选择了不让编译器这么聪明的方法
在实际场景中,b所指的实际对象不会如此本地化,因此编译时是可确定的。因此,选择它是为了不让编译器过于智能,因为它不能解决实际情况。加上一个“告诉它处理”