![](/img/trans.png)
[英]How to refactor a method to a generic one accepting only a subset of types?
[英]How do I restrict accepting only one type in my generic method?
我有一個通用函數foo,它接受任何類型並打印出來。
public static <T> T foo(T... arg) {
List<T> foo = Arrays.asList(arg);
for (T t : foo) {
System.out.println(t);
}
return null;
}
如何確保收到的參數只有一種類型。 例如,{1,'a',3}應該無效。 它應該是所有數字或所有字符。 我想接受所有整數或所有字符。
事實上你可以這樣做:
static <T extends Comparable<T>> void f(T... args) {
System.out.println(java.util.Arrays.toString(args));
}
public static void main(String[] args) {
// all one type -- all of these compile!
f(1, 2, 3); // prints "[1, 2, 3]"
f('a', 'b', 'c'); // prints "[a, b, c]"
f("a", "b", "c"); // prints "[a, b, c]"
f(1D, 2D, 3D); // prints "[1.0, 2.0, 3.0]"
// this is not preventable
f(1, (int)'a', 3); // prints "[1, 97, 3]"
// mixture of types -- none of these compile!
//f(1, 'a', 3); // compilation error!
//f(1, '2', "3"); // compilation error!
//f("a", "b", 'c'); // compilation error!
//f(1, 2, 3D); // compilation error!
}
這利用了以下事實:
Integer implements Comparable<Integer>
Character implements Comparable<Character>
String implements Comparable<String>
Double implements Comparable<Double>
因此,為了匹配這些類型(以及可能的其他類型),我們將T
綁定如下:
這包括諸如java.util.Date
東西,它implements Comparable<Date>
,以及無數其他類型,但如果你還想允許Integer
和Character
,你可能會做的最好。
然而,做牢記Integer
, Character
, String
,都是Object
,所以其實一幫這些混合在一起的是一種類型的列表: Object
。
值得慶幸的是, 並非 Object implements Comparable<Object>
; 否則上述解決方案將無效。
T
部分意味着所有的args
都是相同的類型。
如果要將泛型類型限制為僅某種類型或子類型(例如整數),則可以執行以下操作: -
public static <T extends Integer> T foo(T... arg) {
List<T> foo = Arrays.asList(arg);
for (T t : foo) {
System.out.println(t);
}
return null;
}
我不是一個java開發人員,但你可以做的一個可能的選擇是使用類型為T的對象的泛型集合。
public static <T> T foo(List<T> arg) {
List<T> foo = arg;
for (T t : foo) {
System.out.println(t);
}
return null;
}
你可以這樣做你想做的事情:
YourClass.<Type>foo(params);
特別:
YourClass.<Integer>foo(1, 2, 3);
和
YourClass.<Character>foo('a', 'b', 'c');
您可以利用foo
返回與輸入參數相同類型<T>
的事實。
您可以通過定義返回類型來推斷<T>
:
Integer i1 = 4;
String s = "string";
final Integer i2 = foo(i1, s); // error, only Integer allowed
如果未指定返回類型,則類型<T>
將被推斷為Object
,因此將接受所有子類。
或者,正如@Finbarr所提到的,您可以通過推斷來推斷類型
Foo.<Integer>foo(i1, s); // error, only Integer allowed
要聲明有界類型參數,請列出類型參數的名稱,然后是extends關鍵字,后跟其上限。
以下方法僅接受數字作為參數。
public static <T extends Comparable<T>> T maximum(T firstNumber, T secondNumber)
{
system.out.println(secondNumber.compareTo(firstNumber));
}
如果不使用Comparable擴展它,則compareTo()
將不可用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.