Javagenerics:多个generics参数?
我想知道是否可以编写一个接受多个genericstypes的函数,如下所示:
public int void myfunction(Set<T> a, Set<T> b) { return 5; } Set<Integer> setA = new HashSet<Integer>(); Set<String> setB = new HashSet<String>(); int result = myfunction(setA, setB);
这会工作吗? 每个参数中的generics是否意味着每个参数都必须具有通用的相同typesT?
谢谢!
是的 – 这是可能的(虽然不是与您的方法签名),是的,与您的签名types必须相同。
通过签名, T
必须在呼叫站点与一个单一types(例如String
或 Integer
)相关联。 但是,您可以声明采用多个types参数的方法签名
public <S, T> void func(Set<S> s, Set<T> t)
注意在上面的签名中,我已经在签名本身中声明了typesS
和T
因此,这些与包含该函数的类或接口相关的任何通用types都是不同的和独立的。
public class MyClass<S, T> { public void foo(Set<S> s, Set<T> t); //same type params as on class public <U, V> void bar(Set<U> s, Set<V> t); //type params independent of class }
您可能想看看java.util
包中集合类的一些方法签名。 generics实际上是一个相当复杂的主题,特别是在考虑通配符( ? extends
和? super
)时。 例如,一个可能接受Set<Number>
作为参数的方法通常也应该接受一个Set<Integer>
。 在这种情况下,你会看到这样的签名:
public void baz(Set<? extends T> s);
这里有很多问题可供您参考。
- Javagenerics:List,List <Object>,List <?>
- Javagenerics(通配符)
- C#和Java中的generics和C ++中的模板之间有什么区别?
不知道从函数返回一个int
是什么,虽然你可以做到这一点,如果你想!
您可以在types或方法上声明多个types的variables。 例如,在方法上使用types参数:
<P, Q> int f(Set<P>, Set<Q>) { return 0; }
更甚者,你可以inheritancegenerics:)
@SuppressWarnings("unchecked") public <T extends Something<E>, E extends Enum<E> & SomethingAware> T getSomething(Class<T> clazz) { return (T) somethingHolderMap.get(clazz); }
a和b都必须是同一types的集合。 但没有什么能阻止你写作
myfunction(Set<X> a, Set<Y> b)
在你的函数定义中,你正在约束a和b是相同的types。 你也可以写
public <X,Y> void myFunction(Set<X> s1, Set<Y> s2){...}
你可以按照下面的方法之一:
1)基本,单一types:
//One type public static <T> void fill(List <T> list, T val) { for(int i=0; i<list.size(); i++){ list.set(i, val); } }
2)多种types:
// multiple types as parameters public static <T1, T2> String multipleTypeArgument(T1 val1, T2 val2) { return val1+" "+val2; }
3)下面会引发编译错误,因为'T3不在函数声明部分使用的genericstypes列表中。
//Raised compilation error public static <T1, T2> T3 returnTypeGeneric(T1 val1, T2 val2) { return 0; }
正确:编译好
public static <T1, T2, T3> T3 returnTypeGeneric(T1 val1, T2 val2) { return 0; }
样本分类代码:
package generics.basics; import java.util.ArrayList; import java.util.List; public class GenericMethods { /* Declare the generic type parameter T in this method. After the qualifiers public and static, you put <T> and then followed it by return type, method name, and its parameters. Observe : type of val is 'T' and not '<T>' * */ //One type public static <T> void fill(List <T> list, T val) { for(int i=0; i<list.size(); i++){ list.set(i, val); } } // multiple types as parameters public static <T1, T2> String multipleTypeArgument(T1 val1, T2 val2) { return val1+" "+val2; } /*// Q: To audience -> will this compile ? * * public static <T1, T2> T3 returnTypeGeneric(T1 val1, T2 val2) { return 0; }*/ public static <T1, T2, T3> T3 returnTypeGeneric(T1 val1, T2 val2) { return null; } public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(10); list.add(20); System.out.println(list.toString()); fill(list, 100); System.out.println(list.toString()); List<String> Strlist = new ArrayList<>(); Strlist.add("Chirag"); Strlist.add("Nayak"); System.out.println(Strlist.toString()); fill(Strlist, "GOOD BOY"); System.out.println(Strlist.toString()); System.out.println(multipleTypeArgument("Chirag", 100)); System.out.println(multipleTypeArgument(100,"Nayak")); } }
//类定义结束
示例输出:
[10, 20] [100, 100] [Chirag, Nayak] [GOOD BOY, GOOD BOY] Chirag 100 100 Nayak