是否可以从Java中的对象构造函数中删除泛型类型参数?

时间:2011-06-13 16:24:19

标签: java generics constructor

在Java中,必须写:

Pair<String, String> pair = new Pair<String, String>("one", "two");

如果为你推断出这些类型会很好,所以你至少可以这样做:

Pair<String, String> pair = new Pair("one", "two");

再次跳过通用参数。

你可以制作一个静态的方法,可以像这样作弊:

public static <T, S> Pair<T, S> new_(T one, S two) {
    return new Pair<T, S>(one, two);
}

然后使用它:Pair.new_("one", "two")

是否可以在构造函数中构建类型推理,以便可以避免hack?

我想的是:

public <S,T> Pair(S one, T two) {
    this.one = one;
    this.two = two;
}

但是你遇到了泛型冲突。有没有人有任何想法?

5 个答案:

答案 0 :(得分:7)

通常会有一个帮助方法来暗示你的类型。

Pair<String, String> pair = Pair.of("one", "two");

然后它似乎不是这样的黑客。

如果Java有内置的Pair类,也会很好。 ;)

答案 1 :(得分:4)

在Java 7中,您可以使用“diamond”运算符:

List<String> strings = new ArrayList<>();

Map<String, Int> map = new HashMap<>();

Map<String, List<String>> lolmap = new HashMap<>();

答案 2 :(得分:1)

问题在于声明特定类型的变量,以及该变量要引用的对象的实例化是两个不同的操作。字符串通常很难被误解,但是假设您正在设置数字对(可能是X-Y坐标):

Pair<float,float> myCoords = new Pair(3,4);

这引起了窘境;你声明一个Pair<float, float>,但是分配一个可能被推断为Pair<int,int>的对象,除非编译器被赋予足够的智能以在推断实例化对象时考虑所设置变量的类型泛型类型(极不可能)。 Java泛型,AFAIK,不是协变的,即使它们是,int也不会从float继承。我不知道一种非鸭式的语言可以正确处理这种情况。

答案 3 :(得分:1)

我知道这很累,但这样可以确保代码的类型安全。此代码是合法的Java代码(尽管编译器发出警告):

import java.util.*;

public class Main {
  public static void main(String[] args) {
    ArrayList a = new ArrayList();
    a.add(1);
    ArrayList<String> b = a;
    System.out.println(b.get(0));
  }
}

但是编译器现在无法推断出类型,但是a是与b兼容的赋值。尝试运行它,会发生运行时错误。

答案 4 :(得分:0)

我更喜欢明确的事情。当推断出事物时,它们可能被错误地推断,或者该方法可能被错误地使用而没有任何通知,因为系统推断出如何处理不正确的参数。