[英]Casting objects in a way that we cast Primitive Data Types
我有三个班级: A
, AA
和顶级。 A和AA扩展了Top。
为什么它不能编译:
A a = new A();
AA aa = (AA)a;
但这将:
float f = 4.3f;
int i = (int) f;
类A
和类AA
处于同一层次,但他们并排,所以它们不能被强制转换为另一个。
假设A
类A
定义如下:
public class A extends Top{
public A() {
}
public void foo(int i) {
System.out.println(i);
}
}
而AA
类的定义如下:
public class AA extends Top {
public AA() {
}
public void bar(String s) {
}
}
现在让我们从理论上想象一下,如果您尝试将A
AA
转换为AA
并起作用,那么实际会发生什么:
A a = new A();
(AA) aa = (AA) a;
由于aa
具有静态类型 AA
,因此Java将允许您编写如下代码:
aa.bar("hi!");
由于AA
类具有bar方法,因此BUT aa
具有动态类型 A
,这意味着变量aa
引用的实际对象没有称为bar("hi!")
。
(对象的静态类型告诉您可以对其调用什么方法,而动态类型则告诉您实际具有的方法。)
因此Java会告诉aa
做bar("hi!")
但是aa
不知道要做什么,因为aa
没有定义bar
方法。
您可以在要转换的类中创建转换方法。 在这里,我使用a.cast(B b)方法将类型转换为类型A。
public class A {
public int i;
public A cast(B b){
A a = new A();
a.i=b.i;
return a ;
}
}
public class B {
public int i=10;
}
public class Tester {
public static void main(String[] args) {
B b = new B();
A a= new A();
a=a.cast(b);
System.out.println(a.i);
}
}
Java是一种强类型的编程语言,这意味着要定义每个变量,需要指定其类型,并且对于每个变量,它只能保存属于同一类型的值。 对于基本类型,Java还定义了如何将不同类型相互Widening Primitive Conversion
的规则,其中包括Widening Primitive Conversion
(无信息丢失)和Narrowing Primitive Conversion
(信息可能丢失),您可以在Java官方文档中找到更多详细信息。 所以你可以做int i = (int) f;
的原因int i = (int) f;
是转换规则是在Java Spec中定义的,而Java编译器允许您这样做。 如果尝试,则不能将int a = (int) true
,因为没有将boolean
类型转换为int
的规则。
引用类型的类型转换规则也很简单,当编译器认为b
的类型可能是 A
或类型层次结构中A
某些sub-type
时,编译器仅允许您进行类型转换A a = (A) b
在以下代码中:
Object b = c;
A a = (A) b;
编译器仅知道b是Object
类型,但不知道其特定类型,因为Object
是Java类型层次结构的root
,因此b
的实际类型可能是任何类型,例如type A
,因此编译器将允许您这样做。 如果b
实际上不是 A
,则只能在运行时引发ClassCastException
时发现错误。
另一方面,当编译器清楚地知道 b
不是A
类型时,它会阻止您执行A a = (A) b
:
class A {}
class B {}
如果您具有上述类型A
和B
定义,则编译器具有足够的信息,实例B
绝对不是类型A
,因此当您尝试执行A a = (A) new B()
时,它将给您带来Inconvertible types
的编译错误。 A a = (A) new B()
。 这是使用强类型编程语言的一大好处:保证类型安全(在Java编译时)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.