![](/img/trans.png)
[英]what does this mean: 'private' modifier out of order with the JLS suggestions
[英]jls. return-type-substitutable. What does it mean?
我正在閱讀jls,但遇到了以下術語:
return-type-substitutable
來自jls的片段
如果滿足以下任何條件,則返回類型為R1的方法聲明d1可替換為返回類型為R2的另一個方法d2:
如果R1為空,則R2為空。
如果R1是原始類型,則R2與R1相同。
如果R1是引用類型,則下列條件之一為真:
--R1是R2的子類型,適用於d2(第8.4.4節)的類型參數。
--R1可以通過未經檢查的轉換(第5.1.9節)轉換為R2的子類型。
--d1與d2(第8.4.2節)的簽名不同,並且R1 = | R2 |。
前兩點很明顯。
你能澄清一下嗎
--R1是R2的子類型,適用於d2(第8.4.4節)的類型參數。
--R1可以通過未經檢查的轉換(第5.1.9節)轉換為R2的子類型。
--d1與d2(第8.4.2節)的簽名不同,並且R1 = | R2 |。
謝謝
Luiggi Mendoza的PS
interface Foo {
List<String> foo(String arg1, String arg2);
}
class Bar implements Foo {
@Override
public ArrayList<String> foo(String arg1, String arg2) {
//implementation...
return null;
}
public String foo(String arg1, String arg2, String arg3) {
//implementation...
return null;
}
}
它正在工作。
如果具有返回類型R1的方法聲明d1覆蓋或隱藏了具有返回類型R2的另一個方法d2的聲明,則d1必須是d2的返回類型可替換的(第8.4.5節),否則會發生編譯時錯誤
If R1 is a reference type then **one of the following** is true:
...
--d1 does not have the same signature as d2 (§8.4.2), and R1 = |R2|.
...
碼:
interface Foo {
List<String> foo(String arg1, String arg2);
}
class Bar implements Foo {
@Override
public List<String> anotherName(String arg1, String arg2,Object obj) {
return null;
}
這是編譯錯誤。
R1 == R2( List<String > == List<String>
)
D1!= D2
我在哪里違反規則?
讓我們有這個界面
interface Foo {
List<String> foo(String arg1, String arg2);
}
和一個實現它的類
class Bar implements Foo {
@Override
public List<String> foo(String arg1, String arg2) {
//implementation...
}
}
我們有:
Bar#foo
作為d1
List<String>
返回d1中的R1類型。 Foo#foo
as d2
List<String>
返回d2中的R2類型。 適應d2類型參數(第8.4.4節 )的R1是R2的子類型。
這意味着R1
可以是R2
的子類型,這意味着R1應該通過IS-A測試。 因此,我們可以執行以下操作:
class Bar implements Foo {
@Override
public ArrayList<String> foo(String arg1, String arg2) {
//implementation...
}
}
可以通過未經檢查的轉換將R1轉換為R2的子類型(第5.1.9節 )。
這與泛型更相關。 這意味着即使R1
引發未檢查的覆蓋警告, R1
應通過IS-A測試。 因此,我們可以執行以下操作:
class Bar implements Foo {
@Override
public ArrayList foo(String arg1, String arg2) {
//implementation...
}
}
這意味着重載:
class Bar implements Foo {
@Override
public ArrayList<String> foo(String arg1, String arg2) {
//implementation...
}
public ArrayList<String> foo(String arg1, String arg2, String arg3) {
//implementation...
}
}
如果具有返回類型R1的方法聲明d1覆蓋或隱藏了具有返回類型R2的另一個方法d2的聲明,則d1必須是d2的返回類型可替換的(第8.4.5節),否則會在d2時發生編譯時錯誤(第8.4.2節),並且R1 = | R2 |。
讓我們將其分為幾部分:
首先,我們需要一個方法聲明d2
和一個返回類型R2
:
class SomeClass {
public List<String> d2() {
return null;
}
}
現在,我們定義一個擴展SomeClass
的類,該類定義d1
並返回R1
。
class AnotherClass extends SomeClass {
//@Override annotation means it is overriding a method in parent class
//d2 here is d1
//Object here is R1
@Override
public List<String> d2() {
}
}
如何編譯? 因為d1
可以替代d2
,所以R1
可以代替R2
作為返回類型。 這也稱為協變返回類型 ,在Java教程中有介紹。 從方法返回值 。 另一條規則支持:
如果滿足以下任一條件,則返回類型為R1的方法聲明d1可替換為具有返回類型R2的另一個方法d2:如果R1為引用類型,則以下條件之一為true:d1不相同簽名為d2(第8.4.2節),並且R1 = | R2 |。
這意味着所有這些方法對於覆蓋SomeClass#d2
都是有效的:
class AnotherClass extends SomeClass {
//ArrayList implements List
@Override
public ArrayList<String> d2() {
return null;
}
}
class AnotherClass extends SomeClass {
//raw List can be casted to `List<String>` by unchecked conversion
//means you don't need a explicit cast to convert `List` to `List<String>`
//due to type erasure
@Override
public List d2() {
return null;
}
}
class AnotherClass extends SomeClass {
//combination of both examples above
@Override
public ArrayList d2() {
return null;
}
}
但是這些是無效的實現:
class AnotherClass extends SomeClass {
//the signature is not the same
@Override
public List<String> d1() {
return null;
}
}
class AnotherClass extends SomeClass {
//Set is not a subtype of List
@Override
public Set<String> d2() {
return null;
}
}
class AnotherClass extends SomeClass {
//Collection is not a subtype of List
@Override
public Collection<String> d2() {
return null;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.