2013-06-11 5 views
7

To kompiluje znaleźć za pomocą Eclipse:dlaczego to Eclipse kompiluje ten kod Java, ale nie Ant?

abstract class CollectionView implements Collection<Object> { 

... 
     public Object[] toArray(Object[] o) { 
      if (fast) { 
       return get(map).toArray(o); 
      } else { 
       synchronized (map) { 
        return get(map).toArray(o); 
       } 
      } 
     } 
... 
} 

    class KeySet extends CollectionView implements Set<Object> { 

     protected Collection<Object> get(Map<Object, Object> map) { 
      return map.keySet(); 
     } 

     protected Object iteratorNext(Map.Entry entry) { 
      return entry.getKey(); 
     } 
    } 

ale nie udaje mu się skompilować przy użyciu Ant:

error: KeySet is not abstract and does not override abstract method toArray(T[]) in Set

widzę dlaczego kod będzie kompilować za pomocą Eclipse: Keyset już dziedziczy realizację ToArray (T []) metoda z CollectionView.

Ale dlaczego nie działa, gdy kompiluję za pomocą Ant?

<javac srcdir="src" destdir="bin" debug="on"> 
     <compilerarg value="-Xlint:unchecked"/> 
     <compilerarg value="-Xlint:deprecation"/> 
    </javac> 
+0

To jest trudny. Musi istnieć jakaś różnica w zależnościach lub kolejności zależności? – djangofan

+0

Nie jestem pewien. ale obie klasy są wewnętrznymi klasami tej samej klasy. –

+0

Czy klasa otaczająca implementuje 'toArray()'? –

Odpowiedz

1

Istnieje kilka przypadków, gdzie zaćmienie kompiluje grzywny i javac nie. Jeśli nie masz nic przeciwko, istnieją trzy sposoby, które wiem, aby budować przy użyciu kompilatora Eclipse.

  1. Pakiet eclipse skompilowanych klas (hacky, niezalecane)

  2. używać zasilacza zaćmienie kompilatora z Ant. Po określeniu właściwości build.compiler właściwości wszystkie kompilacje javac będą miały wpływ na kompilację Ant. Możesz ustawić go na "org.eclipse.jdt.core.JDTCompilerAdapter". Zauważ, że będziesz musiał dołączyć tę klasę (i klasy, od której to zależy) w ścieżce klas kompilacji ant. Najprostszym sposobem jest dodanie niezbędnych słoików do lib folderze Ant instalacji

  3. Kiedy budynek z maven skonfigurować ten

     <plugin> 
          <groupId>org.apache.maven.plugins</groupId> 
          <artifactId>maven-compiler-plugin</artifactId> 
          <version>3.1</version> 
          <configuration> 
           <compilerId>eclipse</compilerId> 
           <compilerVersion>1.6</compilerVersion> 
           <source>1.6</source> 
           <target>1.6</target> 
           <optimize>true</optimize> 
          </configuration> 
          <dependencies> 
           <dependency> 
            <groupId>org.codehaus.plexus</groupId> 
            <artifactId>plexus-compiler-eclipse</artifactId> 
            <version>2.2</version> 
           </dependency> 
          </dependencies> 
         </plugin> 
    

w sekcji wtyczek odcinka budowy swojego pom .xml

2

Przede wszystkim powinniśmy zwrócić uwagę na dokładną sygnaturę metody oczekiwanego które mają być realizowane:

<T> T[] toArray(T[] a); 

I obie javac i Eclipse należy ostrzec o tym „” Rodzaj bezpieczeństwo kwestii. A jeśli zmienisz podpis na oczekiwany, javac jest szczęśliwy.

Jeżeli umieścisz @Override metody ToArray, nawet z podpisem, które wykorzystują surowe Object typu, zarówno Eclipse i javac prawidłowo postrzegają ją jako przesłonięcie metody zadeklarowanej przez Collection. Więc problemu tego nie ma.

Niespójność, i myślę, że bug javac, jest to, że każdy realizacja podklasa, javac nie rozpoznaje super metodę Object[] toArray(Object[] o) wdrożyć <T> T[] toArray(T[] a). Jeśli zrobił to dla klasy abstrakcyjnej, powinienem to zrobić dla każdej podklasy.

Po raz pierwszy javac ma błąd na ten temat. Zobacz na przykład: thread. Przeszukałem bazę danych błędów Oracle, nie znalazłem nic o tym, co znalazłeś.

Następnie trzeba obejść: w klasie abstrcat użyj oczekiwanego podpisu; Czy nadpisanie „manually` w subclasss:

public Object[] toArray(Object[] o) { 
    return super.toArray(o); 
}