[英]How do I restrict accepting only one type in my generic method?
I have a generic function foo, which accepts any type and prints them out. 我有一个通用函数foo,它接受任何类型并打印出来。
public static <T> T foo(T... arg) {
List<T> foo = Arrays.asList(arg);
for (T t : foo) {
System.out.println(t);
}
return null;
}
How do I make sure that the arguments received are of only 1 type. 如何确保收到的参数只有一种类型。 For example, {1,'a',3} should be invalid.
例如,{1,'a',3}应该无效。 It should either be all numbers or all characters.
它应该是所有数字或所有字符。 I want to accept either ALL integers or ALL Characters.
我想接受所有整数或所有字符。
You can in fact do something like this: 事实上你可以这样做:
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!
}
This takes advantage of the fact that: 这利用了以下事实:
Integer implements Comparable<Integer>
Character implements Comparable<Character>
String implements Comparable<String>
Double implements Comparable<Double>
So to match those types (and possibly others), we bound T
as follows: 因此,为了匹配这些类型(以及可能的其他类型),我们将
T
绑定如下:
This does include things eg java.util.Date
, which implements Comparable<Date>
, and countless many other types, but is probably the best that you can do if you also want to allow Integer
and Character
. 这包括诸如
java.util.Date
东西,它implements Comparable<Date>
,以及无数其他类型,但如果你还想允许Integer
和Character
,你可能会做的最好。
Nonetheless, do keep in mind that Integer
, Character
, String
, are all Object
, so in fact a bunch of those mixed together IS a list of one type: Object
. 然而,做牢记
Integer
, Character
, String
,都是Object
,所以其实一帮这些混合在一起的是一种类型的列表: Object
。
Thankfully, it's NOT the case that Object implements Comparable<Object>
; 值得庆幸的是, 并非
Object implements Comparable<Object>
; otherwise the above solution wouldn't work. 否则上述解决方案将无效。
The T
part means that all the args
will be the same type. T
部分意味着所有的args
都是相同的类型。
If you wanted to restrict your generic type to be only a certain type or sub-type (eg Integer) you can do the following:- 如果要将泛型类型限制为仅某种类型或子类型(例如整数),则可以执行以下操作: -
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;
}
I'm not a java developer but what you can do as one possible option is use generic collection of objects of type T. 我不是一个java开发人员,但你可以做的一个可能的选择是使用类型为T的对象的泛型集合。
public static <T> T foo(List<T> arg) {
List<T> foo = arg;
for (T t : foo) {
System.out.println(t);
}
return null;
}
You can do what you want to do like this: 你可以这样做你想做的事情:
YourClass.<Type>foo(params);
Specifically: 特别:
YourClass.<Integer>foo(1, 2, 3);
and 和
YourClass.<Character>foo('a', 'b', 'c');
You can take advantage of the fact that foo
returns the same type <T>
as the input parameters. 您可以利用
foo
返回与输入参数相同类型<T>
的事实。
You can infer <T>
by defining the return type: 您可以通过定义返回类型来推断
<T>
:
Integer i1 = 4;
String s = "string";
final Integer i2 = foo(i1, s); // error, only Integer allowed
If you do not specify a return type, the type <T>
will be inferred as Object
, and thus all sub-classes will be accepted. 如果未指定返回类型,则类型
<T>
将被推断为Object
,因此将接受所有子类。
Alternatively, as @Finbarr mentions, you can infer the type via 或者,正如@Finbarr所提到的,您可以通过推断来推断类型
Foo.<Integer>foo(i1, s); // error, only Integer allowed
To declare a bounded type parameter, list the type parameter's name, followed by the extends keyword, followed by its upper bound. 要声明有界类型参数,请列出类型参数的名称,然后是extends关键字,后跟其上限。
Following method will only accept numbers as it's parameters. 以下方法仅接受数字作为参数。
public static <T extends Comparable<T>> T maximum(T firstNumber, T secondNumber)
{
system.out.println(secondNumber.compareTo(firstNumber));
}
If you don't extend it with Comparable then compareTo()
will not be available. 如果不使用Comparable扩展它,则
compareTo()
将不可用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.