免责声明:我是Java泛型和收藏品的新手。
背景:我研究了Java Generics here和here的基础知识。现在我想了解它们如何应用于Hadoop的Mapper(public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable>
)
问题:直到今天,我才在类定义(public class OrderedPair<K,V> implements Pair<K,V>
)中看到占位符,而不是具体的类(public class Me extends Thing<String,Integer,Character>
)。
问题:总的来说,如果我有这个......
public class Me extends Thing<String,Integer,Character>
...“扩展Thing<String,Integer,Character>
”是什么意思?似乎我正在“扩展”Thing - 也就是说,Me子类继承了Thing超类的方法。这种继承是否与Thing<String,String,String>
不同?
澄清:换句话说,扩展没有泛型的类(例如public class X extends Y
)和泛型(public class X extends Y<a,b,c>
)之间有什么区别?
答案 0 :(得分:1)
泛型类可以具有与其一起使用的不同类型(您在实例化其对象时选择使用它的类型)。如果扩展泛型类并且确实在那里放置具体类型,就像你在这里所做的那样:for c in s:
if c in char1:
counter1 += 1
if c in char2:
counter2 += 1
这意味着我正在扩展Thing,但Thing不再是通用的,因为它现在绑定到给定的类型。
以前你可以实例化Thing:
public class Me extends Thing<String,Integer,Character>
但我现在受约束,你不能再为它选择类型了。
Thing<String, Character, Integer> myThing = new Thing<>();
您还可以使用实际的泛型类型扩展Thing,因此您的Me类仍然是通用的。
Me myMe = new Me();
有了这个,您可以使用给定的泛型类型初始化Me,这些类型将被传递给通用Thing。
你也可以部分地做。所以某些类型的东西是固定的,有些东西可以在你实例化我时自由选择。
public class <T, K, V> Me extends Thing<T, K, V>
...
// init with
Me<String, Character, Integer> myMe = new Me<>();
答案 1 :(得分:0)
扩展具有泛型类型的类时,可以选择指定子类将在其下工作的类型。例如,protected
将使用class MyList extends ArrayList<String>
方法,但将特定于字符串。
以同样的方式,当您扩展ArrayList
时,您需要指定映射器将要处理的参数类型。您可以通过提供类型参数Mapper
声明来实现。
答案 2 :(得分:0)
澄清:换句话说,有什么区别
扩展没有泛型的类(例如,公共类X扩展Y)
和泛型(public class X extends Y<a,b,c>
)?
不同之处在于,在第二种情况(泛型类)中,如果要编译正常,则必须符合泛型类指定的类型的约束,否则应声明原始子类。
通常,泛型类指定的类型由它的方法使用
因此,正确定义它们很重要
您主要有3个案例。
采用此泛型类声明,指定3个参数并在myMethod()
方法中使用它们:
public class Y <A extends AClass,B extends BClass, C extends CClass> {
public void myMethod(A a, B b, C c){
...
}
}
1)您的子类是原始类:
public class Z extends Y {
....
}
在这种情况下,它编译得很好但有警告
您在方法调用中失去了泛型的好处。
编译器将使用此签名考虑Z
的方法:
public void myMethod(Object a, Object b, Object c){
...
}
2)您的子类是一个通用的兼容子类:
public class Z extends Y<ASubClass,BSubClass,CSubClass> {
....
}
编译器将使用此签名考虑Z
的方法:
public void myMethod(ASubClass a, BSubClass b, CSubClass c){
...
}
3)您的子类是泛型类,但不符合父类指定的参数,您有编译错误。
public class Z extends Y<BSubClass,ASubClass,CSubClass> {
....
}
答案 3 :(得分:-1)
如果超类型使用泛型,那么,对于任何泛型类型,在没有泛型参数的情况下引用它是使用原始类型的错误。您必须为泛型类型中的每个类型变量使用通用类型变量或具体类型。例如,变量就像
Thing<String, Integer, Character> thing = new Thing<>();
当然,这与
不同Thing<String, String, String> thing = ...
因为它处理不同的类型!
同样适用于继承。在您的情况下,您将类型参数锁定为具体类型。
public class SomeThing extends Thing<String, Integer, Character> { ...
锁定SomeThing
可以处理的类型,因此SomeThing
实际上不是通用类。