2015-10-08 40 views
6

faz:stanie używać typ skrzyżowania gdy hipotetyczna klasy wymaga modyfikacji Dostęp

interface PublicCloneable { 
    Object clone(); 
} 

interface HasPosition { 
    // doesn't matter 
} 

próba wykorzystania typ skrzyżowania:

@SuppressWarnings("unchecked") 
<E extends PublicCloneable & HasPosition> E cloneAndIncrementPosition(E elem) { 
    final E clone = (E)elem.clone(); 
    // rest omitted 
} 

Próbowano opracować z javac 1.8.0_60:

$ javac xx.java 
xx.java:13: error: clone() in Object cannot implement clone() in PublicCloneable 
    <E extends PublicCloneable & HasPosition> E cloneAndIncrementPosition(E elem) { 
    ^
    attempting to assign weaker access privileges; was public 
xx.java:14: error: clone() has protected access in Object 
     final E clone = (E)elem.clone(); 
          ^
2 errors 

Dlaczego ten typ przecięcia jest nieprawidłowy dla javac?

+0

Co ciekawe, jeśli usuniesz górną granicę 'HasPosition' z' E', to kompiluje. – rgettman

+0

To kompiluje się na Eclipse ... –

Odpowiedz

8

To wygląda jak błąd javac.

http://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.4

członkowie typu X o zmiennej związanej T & I1 & ... & W oznacza członków rodzaju przecięcia (§4.9) T & I1 & ... & W

http://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.9

Każdy rodzaj przecięcie T1 & ... & Tn indukuje hipotetycznego klasy lub interfejsu dla celów identyfikacji członków rodzaju skrzyżowania ...

Jeśli Ck jest Object, hipotetyczną interfejs jest indukowany ma ... bezpośredni superinterfaces T1' , ..., Tn”

Dlatego dla PublicCloneable & HasPosition, hipotetyczną interfejs został wprowadzony, rozszerzenie obu z nich, co powinno być OK.

+0

Dzięki, właśnie to podejrzewałem. Cieszę się, że się zgadzasz. – Archie

+1

Cóż, ta część specyfikacji jest źle napisana i nie jest spójna pod bliższym spojrzeniem. W każdym przypadku Twój przypadek użycia wygląda całkowicie legalnie i powinien zostać zaakceptowany. – ZhongYu

+0

Dzięki za wyjaśnienie! Jakieś sposoby na powstrzymanie tego błędu i skompilowanie takiego kodu? –

0

Jak pierwszy błąd próbuje ci powiedzieć, twój kod nie może działać, ponieważ ograniczasz się do typów z dwoma niekompatybilnymi sygnaturami dla metody clone().

+0

np. 'Klon' HasPosition' (dziedziczony z 'Object') jest' protected', ale 'PublicCloneable' '' clone', ponieważ jest to interfejs, jest 'public'. Czy to prawda? –