【问题标题】:Java (Android) - types, generics, constructor signature, retrieving references to ClassJava (Android) - 类型、泛型、构造函数签名、检索对 Class 的引用
【发布时间】:2012-01-14 07:47:27
【问题描述】:

我搜索了 SO 并找到了几个与我的问题明显相关的答案,并且还阅读了以下内容:

http://docs.oracle.com/javase/tutorial/java/generics/erasure.html http://www.artima.com/weblogs/viewpost.jsp?thread=208860 http://docs.oracle.com/javase/tutorial/extra/generics/index.html http://docs.oracle.com/javase/tutorial/java/generics/genmethods.html

但它们有点超出我的想象(我对 Java 和 Android 还很陌生)。

我正在尝试了解如何在自定义类中实现泛型。我认为一个例子是最好的解释方式。

假设我从这个基类开始:

import java.util.ArrayList;

import android.content.Context;
import android.widget.ImageView;

public class ViewPool {

    private ArrayList<ImageView> employed;
    private ArrayList<ImageView> unemployed;

    private Context context;

    public ViewPool(Context context){

        this.context = context;

        employed = new ArrayList<ImageView>();
        unemployed = new ArrayList<ImageView>();

    }

    public ImageView employView(){      
        ImageView v;
        if(unemployed.size() > 0){
            v = unemployed.get(0);
            unemployed.remove(v);
        } else {
            v = new ImageView(context);
        }
        employed.add(v);
        return v;
    }

    public void retireView(ImageView v){
        if(employed.contains(v)){
            employed.remove(v);
            unemployed.add(v);
        }
    }
}

现在假设我想修改上面的内容以使用任何 View 类型,传递如下:

new ViewPool<ImageView>(this);

或者...

new ViewPool<TextView>(this);

我将如何重写上面列出的类以接受这样的类型?我最初的尝试,比如下一个代码块,失败的原因可能很明显......

public class ViewPool<E> {
...
    public E employView(){      
        E v;
        if(unemployed.size() > 0){
            v = unemployed.get(0);
            unemployed.remove(v);
        } else {
            v = new E(context);  // this line's obviously bad, but not sure what would be correct
        }
        employed.add(v);
        return v;
    }
...

谢谢

【问题讨论】:

    标签: java android


    【解决方案1】:

    你可以试试

     public class ViewPool<E extends View>
    

    然后要实例化您的视图,您可以使用带有签名的工厂:

     public abstract class ViewFactory<E extends View> {
        public E createView( Context c );
     }
    

    并在您的视图池中使用它来获取 E 的新实例,在构建时为视图池注入依赖项:

    public class ViewPool<E extends View> {
    
    ViewFactory<E> factory;
    
    public viewpool( ViewFactory<E> factory ) {
       this.factory = factory;
    }
    
    public E employView(){      
        E v;
        if(unemployed.size() > 0){
            v = unemployed.get(0);
            unemployed.remove(v);
        } else {
            v = factory.createView( context );  
        }
        employed.add(v);
        return v;
    }
    

    }

    然后使用以下方法创建您的视池:

    ViewFactory<TextView> factory = new ViewFactory<TextView>() { 
        public TextView createView( Context c ) {
           return new TextView( c );
        }
    }
    new ViewPool<TextView>( factory );
    

    【讨论】:

    • 感谢您的回复...那么我将如何获取对泛型的引用以便实例化一个新的
    • 看我的例子,你应该使用工厂来实现这个。 java中没有构造函数的继承,因此不可能使用任何通用形式的构造函数从泛型符号创建视图。解决方法(实际上是一个好的设计)是使用工厂。此外,它还有两个优点:将池与池中实例的创建分开,并明确声明对负责创建对象的对象的依赖。
    • 是的,我的第一条评论中的问题是在您的示例出现之前。我看到你在做什么,并且可以欣赏这种模式。谢谢
    猜你喜欢
    • 1970-01-01
    • 2020-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-12
    • 1970-01-01
    • 1970-01-01
    • 2010-10-16
    相关资源
    最近更新 更多