2011-08-14 21 views
9

yoluyla derleme değil, aşağıdaki yapıya sahiptir:Kovariant Dönüş Türü JavaC

Javac aşağıdaki iletiyle başarısız
public interface BarReturn {} 
public interface FooReturn {} 
public interface FooBarReturn extends FooReturn, BarReturn {} 

public interface Foo { 
    FooReturn fooBar(); 
} 

public interface Bar { 
    BarReturn fooBar(); 
} 

public interface FooBar extends Foo, Bar { 
    FooBarReturn fooBar(); 
} 

: Ancak

FooBar.java:2: types Bar and Foo are incompatible; both define fooBar(), but with unrelated return types 
public interface FooBar extends Foo, Bar { 
    ^
1 error 

Eclipse ince derlemek ve bildiğim kadarıyla yapabilirsiniz Görebildiğim gibi - FooBar'ın fooBar() yöntemi, hem Foo hem de Bar'ın fooBar() yönteminin kontratını kovaryant geri dönüşler kullanarak karşılamaktadır.

Bu, Eclipse derlemesinde veya javac'ta bir hata mı? Ya da javac'ı derlemek için ikna etmenin bir yolu var mı? Başvuru için benim Javac seçenekleri şuna benzer: Sen filanca arayüzünde Foo ve Bar hem uzatıyoruz

javac -d /tmp/covariant/target/classes -sourcepath /tmp/covariant/src/main/java: /tmp/covariant/src/main/java/Foo.java /tmp/covariant/src/main/java/BarReturn.java /tmp/covariant/src/main/java/FooBarReturn.java /tmp/covariant/src/main/java/Bar.java /tmp/covariant/src/main/java/FooReturn.java /tmp/covariant/src/main/java/FooBar.java -g -nowarn -target 1.6 -source 1.6 
+0

Open-jdk derleyici sürüm 1.6.0_22 ile aynı sorun. ama java7'de çalışıyor. –

+0

Sadece test ettim ve evet, yani öyle - harika. –

+0

Mümkün [çoğalt] (http://stackoverflow.com/questions/11343238/java-implementing-multiple-interfaces-with-same-method-and-different-return-ty)? – amaidment

cevap

3

. Bu nedenle, uyumsuz dönüş türleriyle iki yöntemi miras aldınız. Java ko-varyansına sadece Liskov ikamesi uygulandığında izin verilir. Aka, geçersiz aday türlerinin hemen hemen geçersiz kılma türünün bir alt sınıfı olması gerekir. Bu gerektiği derleme gibi bir şey yukarıdaki örnekte

:

public interface BarReturn {} 
public interface FooReturn {} 
public interface FooBarReturn extends FooReturn, BarReturn {} 

public interface Foo { 
    FooReturn fooBar(); 
} 

public interface FooBar extends Foo{ 
    FooBarReturn fooBar(); 
} 
+0

OP kodunda, geçersiz kılma yönteminin dönüş türü *, geçersiz kılınan yöntemlerin her ikisinin de dönüş türlerini alt eder. Dolayısıyla akademik açıdan bakıldığında, OP'nin kodunun geçerli olmamasının bir nedeni yoktur. –

1

The JLS (§9.4.1) diyor ki:

bir arayüz geçersiz_kılınacak_ip_numarası eşdeğer imzalarla çeşitli yöntemler miras mümkündür (§ 8.4.2). 'da böyle bir durumun kendisi bir derleme zamanı hatasına neden olmaz. Arabirim, tüm yöntemleri devraldığı için olarak kabul edilir. Ancak, devralınan yöntemlerden biri 'un diğer herhangi bir kalıtsal yöntem için döndürülebilir tür olması gerekir; aksi takdirde bir derleme zamanı hatası (maddeleri bu durumda değil neden hataları yapmak atar.)

Bu yüzden o Javac doğru olduğunu söyleyebilirim oluşur. Ama bu bana avukat jargonuna benziyor, bu yüzden yanılıyor olabilirim.

1

Bu javaranch discussion numaralı yanıtın bir cevabın bir javac hatası olduğunu varsayar gibi görünüyor. Ancak, başvurulan bug url görünmüyor.

+0

[JDK-7u4] gibi görünüyor (http://www.oracle.com/technetwork/java/javase/downloads/jdk-7u4-downloads-1591156.html) hatayı düzeltir. – Georg

1

bir çözüm olarak,

interface Foo1 extends Foo { 
    FooBarReturn fooBar(); 
} 
interface Bar1 extends Bar { 
    FooBarReturn fooBar(); 
} 
public interface FooBar extends Foo1, Bar1 { } 

oldukça Değil yapabilirdi ama hile yapmak gerekir.

+1

Teşekkürler, bu iyi bir fikir - ancak OpenJDK 7'nin javac'ını ve eclipse derleyicisi ile derledikçe ekstra tipler kullanmadan etrafta çalışabilirim. –

+1

Bu işe yaramıyor gibi görünüyor, jdk6'nın javac hala 'türleri Bar1 ve Foo1 uyumsuz; her ikisi de fooBar() işlevini, ancak ilişkisiz döndürme türleriyle tanımlar. –

1

Aynı sorun vardı ve Oracle'dan JDK 7'yi kullanarak iyi görünüyor.

İlgili konular