铸造分析
我是一个Java新手,最近我进入一些思考以下Android
示例代码:铸造分析
TextView txt = (TextView) findViewById(R.id.activity_display_message);
TextView
是View
类的子类。并且findViewById
返回一个View
对象。
我想了解如何以及为什么我们需要显式转换返回View
到TextView
当返回的对象必须是实际上是一个TextView
,否则铸件将引发转换异常。
所以,这是我试图模仿是怎么回事幕后与此样机代码:
class View{}
class TextView extends View{}
public class A{
// simple hard coded check of the ID
public static View findViewById(int id){
if (id == 1){
return new View();
}
else{
return new TextView();
//return ((View)new TextView()); // This also works
}
}
public static void main(String[] args){
TextView txt = (TextView)findViewById(2); // Works fine
//TextView txt2 = findViewById(2); INCOMPATIBLE TYPES ERROR because the returned type is View
View v = findViewById(2); // Works fine
View view = new View();
//TextView test = (TextView) view; // cast error
View view2 = new TextView();
TextView test2 = (TextView) view2; // Works OK
}
}
结论:
原来,findViewById
实际上投射到View
任何返回的元素。我想这是因为该方法的定义返回值是View
,Java自动将结果转换为View
。
请告诉我是否正确。
当您在问题描述,findViewById(R.id.activity_display_message);
返回View
对象,在这种情况下,你的程序员知道,这个特殊的View
实际上是一个TextView
对象,但findViewById
只承诺返回一个View
,或任何类的一个实例从View
下降,因为从View
下降的任何类仍然是View
,它只是可能有更多的具体细节。
所有findViewById
保证返回的东西是或延伸View
。如果要将返回的对象视为View
的特定子类,则需要将由findViewById
返回的对象转换为该子类。
从你的榜样, View view = new View(); // This is a View, it is NOT a TextView View textView = new TextView(); // TextView is a View, but it also has TextView stuff going on... //TextView test = (TextView) view; // cast error
原因异常的情况下,1 BCZ您的视图类是不知道叫TextView的任何子类...这里作为案例2的TextView是知道它属于家庭的View类。
upcast - 将子类型对象转换为超类型,这称为upcast。在Java中,我们不需要添加明确的转换,并且可以直接分配对象。编译器会理解并将值转换为超类型。通过这样做,我们将一个对象提升到一个通用的级别。如果我们愿意,我们可以添加一个明确的演员,而不是问题。
downcast - 将超类型投射到子类型称为downcast。这是主要完成的演员。通过这样做,我们告诉编译器,存储在基础对象中的值是超类型的。然后我们要求运行时分配值。由于downcast,我们可以访问该对象的子类型的方法。
ClassCastExcpetion - 我们在下降的ClassCastException中。原则上,我们保证编译器的实例值是子类型,并要求它进行转换。但在运行期间,由于无法预料的情况,该值不是预期的子类型。在这种情况下,我们得到ClassCastException。
即使该方法返回View
,因为TextView
是View
的子类,所以该方法可以安全地返回。
就拿以下法律分配:
View view = new TextView(); // Legal, no compiler errors. TextView is a subclass of View, so it can be safely 'downgraded'
而下面的非法转让:
TextView textView = new View(); // Illegal, compatibility error
这是完全相同的方式与返回时,TextView
被降级为View
。关于您是否可以确定是否返回TextView
的问题,您可以使用instanceof
运算符。
可能是这个http://stackoverflow.com/questions/22805869/cast-result-findviewbyid-android-method help! – Raghunandan
是的你是对的,java正在以这种方式工作 – RMachnik