Java 如何限制在泛型方法中只接受一种类型?

Java 如何限制在泛型方法中只接受一种类型?,java,types,generics,Java,Types,Generics,我有一个通用函数foo,它接受任何类型并打印出来 public static <T> T foo(T... arg) { List<T> foo = Arrays.asList(arg); for (T t : foo) { System.out.println(t); } return null; } publicstatictfoo(T…arg){ List foo=Arrays.asList(arg); for(T:

我有一个通用函数foo,它接受任何类型并打印出来

public static <T> T foo(T... arg) {
    List<T> foo = Arrays.asList(arg);
    for (T t : foo) {
      System.out.println(t);
    }
    return null;
  }
publicstatictfoo(T…arg){
List foo=Arrays.asList(arg);
for(T:foo){
系统输出打印ln(t);
}
返回null;
}

如何确保收到的参数仅为1种类型。例如,{1,'a',3}应该无效。它应该是所有数字或所有字符。我想接受所有整数或所有字符。

T部分意味着所有的
参数都是相同的类型

如果要将泛型类型限制为仅为特定类型或子类型(例如整数),可以执行以下操作:-

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;
  }
publicstatictfoo(T…arg){
List foo=Arrays.asList(arg);
for(T:foo){
系统输出打印ln(t);
}
返回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; 
  } 
publicstatictfoo(列表参数){
列表foo=arg;
对于(T:foo){
系统输出打印ln(t);
} 
返回null;
} 

事实上,您可以这样做:

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!
}
YourClass.<Type>foo(params);
static void f(T…args){
System.out.println(java.util.Arrays.toString(args));
}
公共静态void main(字符串[]args){
//所有一种类型--所有这些都可以编译!
f(1,2,3);//打印“[1,2,3]”
f('a','b','c');//打印“[a,b,c]”
f(“a”,“b”,“c”);//打印“[a,b,c]”
f(1D,2D,3D);//打印“[1.0,2.0,3.0]”
//这是无法避免的
f(1,(int)'a',3);//打印“[1,97,3]”
//混合类型--这些类型都不能编译!
//f(1,'a',3);//编译错误!
//f(1,'2',“3”);//编译错误!
//f(“a”、“b”、“c”);//编译错误!
//f(1,2,3D);//编译错误!
}
这充分利用了以下事实:

因此,为了匹配这些类型(可能还有其他类型),我们将
T
绑定如下:

这确实包括一些东西,例如,
实现可比较的
,以及无数其他类型,但如果您还想允许
整数
字符
,这可能是您能做的最好的事情


尽管如此,请务必记住,
整数
字符
字符串
,都是
对象
,因此实际上,一堆混合在一起的是一个类型的列表:
对象


谢天谢地,不是
对象实现可比较的
;否则上述解决方案将不起作用。

您可以这样做:

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!
}
YourClass.<Type>foo(params);
YourClass.foo(params);
具体而言:

YourClass.<Integer>foo(1, 2, 3);
YourClass.foo(1,2,3);

YourClass.foo('a','b','c');

要声明有界类型参数,请列出类型参数的名称,后跟extends关键字,后跟其上限

以下方法将只接受数字作为其参数

public static <T extends Comparable<T>> T maximum(T firstNumber, T secondNumber)
{                      
   system.out.println(secondNumber.compareTo(firstNumber));
}
publicstatict最大值(T firstNumber,T secondNumber)
{                      
system.out.println(secondNumber.compareTo(firstNumber));
}

如果不使用Comparable扩展它,则
compareTo()
将不可用。

您可以利用
foo
返回与输入参数相同类型的
这一事实

public static <T extends Comparable<T>> T maximum(T firstNumber, T secondNumber)
{                      
   system.out.println(secondNumber.compareTo(firstNumber));
}
您可以通过定义返回类型推断

Integer i1 = 4;
String s = "string";

final Integer i2 = foo(i1, s); // error, only Integer allowed
如果不指定返回类型,类型
将被推断为
对象
,因此所有子类都将被接受

或者,正如@Finbarr提到的,您可以通过

Foo.<Integer>foo(i1, s); // error, only Integer allowed
Foo.Foo(i1,s);//错误,只允许整数

您是否检查了您的方法?它对{1,'a',3}有效吗?@hgulyan:会的,因为T将被推断为类型对象。看我的答案-这是可能的。你不能这样写。这意味着,他需要两种不同的方法——一种是数字,另一种是字符。请你在问题中举个例子好吗?你怎么知道你需要接受哪种类型?聪明。顺便问一下,你住在这里吗?