铸造分析

问题描述:

我是一个Java新手,最近我进入一些思考以下Android示例代码:铸造分析

TextView txt = (TextView) findViewById(R.id.activity_display_message);

TextViewView类的子类。并且findViewById返回一个View对象。

我想了解如何以及为什么我们需要显式转换返回ViewTextView当返回的对象必须是实际上是一个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

请告诉我是否正确。

+0

可能是这个http://*.com/questions/22805869/cast-result-findviewbyid-android-method help! – Raghunandan

+0

是的你是对的,java正在以这种方式工作 – RMachnik

当您在问题描述,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,因为TextViewView的子类,所以该方法可以安全地返回。

就拿以下法律分配:

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运算符。