2014-06-20 17 views
7

Przed Java 7 składni poniżej użyto do utworzenia ArrayList,Korzystanie z operatorem diament w Javie 7

ArrayList<Integer> ints = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5,6,7)); 

Ale ponieważ Java 7 możemy pominąć typu rodzajowego w IE konstruktora,

ArrayList<Integer> ints = new ArrayList<>(Arrays.asList(1,2,3,4,5,6,7)); 

ale gdy próbowałem zrobić coś takiego,

ArrayList<Number> nums = new ArrayList<>(Arrays.asList(1,2,3,4,4,5.5,6.6,7.7)); 

pojawia się błąd, ale kiedy wspominając o ogólny typ po prawej stronie czyli

ArrayList<Number> nums = new ArrayList<Number>(Arrays.asList(1,2,3,4,5.5,6.6,7.7)); 

Kod działa idealnie. Jaki może być tego powód?

Dzięki z góry.

+0

Nie mogę pobrać konkretnych fragmentów z JLS, które zmieniły się między Java 7 i 8, aby to wspierać, więc to jest komentarz, ale jeśli pamięć obsługuje Java 8 rozszerzyła rodzaje wnioskowania, które można wykonać, wierzę, że umożliwiając przeszukanie supertekstów i/lub uwzględnienie dodatkowego kontekstu. Twój trzeci fragment kodu kompiluje się bez skarg w języku Java 8. – awksp

Odpowiedz

4

Arrays.asList to metoda rodzajowa, więc technicznie, może być powoływana jako:

Arrays.<Number> asList(1, 2, 3); 

Jeszcze przed Java 7, język może zrobić pewną ograniczoną wnioskowanie do wyeliminowania tego, gdy lewa strona była znana, jak w

final List<Number> nums = Arrays.asList(1, 2, 3); 

wygląda na to, natknął się na krawędzi w przypadku, gdzie dwa rodzaje wnioskowania nie może być z powodzeniem w połączeniu, gdzie wnioskowanie diament i sposób rodzajowy wnioskowanie nie układa. Jestem pewna, że ​​również the JLS sheds more light on this, jeśli miałbyś go przeglądnąć.

3

Java Generics są niezmienne, a tablice są kowariantami.

Jeśli rodzajowych w Javie były kowariantna, jeśli A jest podtypem B, następnie List[A] jest podtypem List[B]. Ale tak nie jest w Javie. (Scala ma wdrożenie kowariancji. W Scala, jeśli B rozciąga A, następnie List[B] rozciąga List[A])

Ale String[] jest podtypem Object[]

Stąd ArrayList<Double> nie mogą być oddane do ArrayList<Number> jak w Twoim przypadku.