我正在尝试理解Java中的泛型。我在Android工作室工作。我有一个Word
类,我有一个ArrayList
的Word
对象。
ArrayList<Word> words = new ArrayList<>();
我试着像这样制作一个通用类
public class wordAdapter<T> extends ArrayAdapter<T> {
public wordAdapter(Context context, ArrayList<T> object) {
super(context, 0, object);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Word wordItem = getItem(position);
// This line gives an error because it needs to be casted to "Word"
// Rest of the code
}
}
现在,我的问题是编译器抱怨的原因?当我使用这个类时,我会传递一个包含ArrayList
对象的Word
。所以,据我所知,以下代码行:
wordAdapter<Word> adapter = new wordAdapter<>(this, words);
应该将类型参数<T>
转换为<Word>
。
我不明白为什么编译器将从getItem(position)
获得的对象视为Object
对象而不是Word
对象。另外我想知道因为它是通用的,编译器是否应该忽略这些东西?它如何识别我将提供什么样的物体?
如果这样定义
public class MyClass<T> extends SomeClass<T>{
public T someMethod(){
// T could be any type. Could be Word, could be String, ......
T someObject = super.getItem();
return someObject
}
}
T是类MyClass
中的未定义类型,因为它是通用的。以后任何类型都可以通过。
MyClass<Word> instance1 = new MyClass<Word>();
MyClass<String> instance2 = new MyClass<String>();
Word value1 = instance1.someMethod();
String value2 = instance2.someMethod();
因此,在MyClass
内部操作时,您不知道稍后将定义哪种类型。
您需要做的是定义类中的类型以便能够使用它。因此,不是稍后从外部传递泛型类型,而是在内部定义它
public class WordClass extends SomeClass<Word>{
public Word someMethod(){
// since the generic type is now defined as Word, you can reference it as such
Word wordObject = super.getItem();
return wordObject;
}
}
因为在你的情况下类型是未知的,但你试图将它定义为Word,你需要添加一个所谓的强制转换。换句话说,告诉java将返回的未知类型看作单词类型的对象。如果你只使用你的类用于Word它会工作,但是很丑陋和不必要。但是如果你以后再使用它,那就说Strings它会破坏,因为String对象不能被转换为word对象
编辑: 我只是在你的一条评论中读到你想为所有类型的数据类型创建一个泛型类,它可以使用特定于类型的函数。
从技术上讲,这可以通过类型检查然后投射它们来实现。但这会非常难看。
public class UglyAdapter<T> extends ArrayAdapter<T>{
public void doTypeSpecificStuff(T obj){
Class<T> objectClass = obj.getClass();
if(objectClass.equals(Integer.class)){
Integer intObj = (Integer) obj;
// here you can call Integer-specific methods
}else if(objectClass.equals(String.class)){
String strObj = (String) obj;
// here you can call String-specific methods
}
else if(objectClass.equals(Word.class)){
Word wordObj = (Word) obj;
// here you can call Word-specific methods
}
else{
// object is unsupported type. Throw exception or do whatever
}
}
}
然而,通常的方法是为您需要支持的每种类型创建一个适配器。这样做是非常难看的,根本不应该这样做。
如果WordAdapter
是包含ArrayAdapter
元素的Word
,则应定义为:
public class WordAdapter extends ArrayAdapter<Word> {
public WordAdapter(Context context, ArrayList<Word> object) {
super(context, 0, object);
}
...
}
这样getItem(position)
将返回Word
。