Android编码中的<t extends =“”view =“”>是否有任何意义?</t>

时间:2013-01-09 23:01:56

标签: java android generics nested-generics

我尝试定义一个包装android.view.View及其子类的类,并包含一些关于渲染的信息(人们可能将其称为View Model或PresentationModel)。

public class MyClass<T extends View>
{
    private T view;
    private Blah blah;     
}

我的原始问题是我是否应该对视图变量的类型进行参数化。 Java的通用实现似乎相当简单(例如,所有类型参数信息在编译时都被删除),我可以在这里找到两个可能的优点。

1)即使我仍然需要在我的代码中的某处指定类型,向下倾斜看起来更酷。

@SuppressWarnings("unchecked")
public final <U extends View> U getView()
{
    return (U) view;
}

以上,

Button btn = (Button) obj.getView();
((LinearLayout) obj).addView(view);

变为

Button btn = obj.getView();
obj.<LinearLayout>addView(view);

2)我或许可以编写一些多态代码;

@Override
public void bringToFront()
{
    // stuff
}

如果某个子类重新定义了一个方法,

public final T getView()
{
    return view;
}

以上,

obj.bringToFront();

可能会有不同的行为,具体取决于我们提供的类型参数。最大的问题是我不知道Google的android框架中是否存在任何实际覆盖情况。

目前,我不会使用Generics,因为显然我不能将HashMap与泛型类一起使用。

Map<String, MyClass<View>> objs = new HashMap<String, MyClass<View>>();
MtClass<Button> obj = objs.get(key);    // type mismatch    

1 个答案:

答案 0 :(得分:2)

2)不正确,至少在你的例子中。您提供的功能不是多态的,因此基于T不会有所不同。当然,子类可以重新定义行为,但这与T无关。

对于1),是的,它确实使代码更漂亮,但它也使它更加不可取。考虑到您拥有视图T的类型,为什么要将其转换为U?根据您上面给出的代码,这显然是非法的,如果您没有强制转换,它将是编译时错误,但现在只是一个运行时错误,除非类型恰好匹配。即如果您有MyClass<Button>并定义了T getView(),则代码可以在不使用U强制转换的情况下使用,或者根本使用类型参数U,而MyClass<TextView>则会在getView()上导致运行时错误,尽管它正确编译。

关于最后一点,当您从Map<K, V>检索对象时,您只能证明该对象是V,而不是V的子类型,这就是为什么最后一个例子没有编译。

总的来说,泛型用于增加代码重用,同时强制执行类型安全,但是您提供的示例似乎只执行前者,并且将类型安全性抛出窗口(公平地说,就是Android UI编程一般来说)。在您给出的示例中,似乎仿制药不会对您造成太大伤害。