简体   繁体   中英

Is is possible to remove generic type parameters from object constructor in Java?

In Java it is tiring to have to write:

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

It would be nice if the types were inferred for you so you could at least do this:

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

And skip the generic params again.

You can make a static method that can cheat around it like so:

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

And then use it like: Pair.new_("one", "two") .

Is it possible to build the type inferencing into the constructor so that hack can be avoided?

I was thinking of something like:

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

But then you run into generic type collisions. Does anyone have any thoughts?

It s common to have a helper method which will imply the types for you.

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

then it doesn't seem like such a hack.

It would also be nice if Java had a built in Pair class. ;)

In Java 7 you can use the "diamond" operator:

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

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

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

The problem is that the declaration of a variable of a particular type, and the instantiation of an object to be referenced by that variable, are two different operations. Strings are generally hard to mistake, but let's say you were setting up pairs of numbers (maybe XY coordinates):

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

This brings up a quandary; you're declaring a Pair<float, float> , but assigning an object that would probably be inferred as Pair<int,int> , unless the compiler were given enough intelligence to take the type of the variable being set into account when inferring the instantiated object's generic types (highly unlikely). Java generics, AFAIK, are not covariant, and even if they were, int does not inherit from float. I don't know of a non-duck-typed language that would handle a situation like this correctly.

I know it's tiring but that way you ensure type safety of your code. This code is a legal Java code (despite of the warning from the compiler):

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));
  }
}

But the compiler cannot infer the type now, yet a is assignment compatible with b. Try running it, and a runtime error would occur.

I prefer things to be explicit. When things are inferred, they can be inferred incorrectly, or the method can be used incorrectly without any notice because the system infers how to handle the incorrect arguments.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM