简体   繁体   English

如何限制在我的通用方法中仅接受一种类型?

[英]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: 这利用了以下事实:

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> ,以及无数其他类型,但如果你还想允许IntegerCharacter ,你可能会做的最好。


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 . 然而,做牢记IntegerCharacterString ,都是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.

相关问题 如何将方法重构为只接受类型子集的泛型方法? - How to refactor a method to a generic one accepting only a subset of types? 如何在实现中确保泛型方法的类型? - How do I ensure the type of a generic method in my implementation? 如何在Java中将泛型类型限制为特定类型? - How do I restrict a generic type to specific types in java? 如何仅针对集合的Set和List类型限制我的方法参数,而不是Map? - How can I restrict my method arguments for only Set and List type of collection, not Map? 如何限制方法仅接受对象作为参数而不是类对象作为类型文字? - How do I restrict method to accept only object as parameter instead of Class Objects as Type Literals? 我的抽象类中有一个通用方法。 我该如何运作? - I have one generic method in my abstract class. How do I make it work? 如何限制arraylist在泛型之前只接受特定类型的对象 - How can I restrict the arraylist to accept only a specfic type of object prior to generic 如何使用泛型来限制子类中的方法参数类型? - How to use generic to restrict method parameter type in subclass? 如何限制接口的通用类型只接受实现者类 - How to restrict generic type of interface to accept only implementor class 如何限制 Class 类型的方法参数不能是泛型? - How to restrict that method param of type Class cannot be generic?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM