2011-04-06 483 views
71

可以採用兩種Java方法同名不同返回類型?方法的返回類型是不同的,並且它們使用相同方法的名稱進行聲明。兩種Java方法可以使用不同的返回類型具有相同的名稱嗎?

允許嗎?

+10

@Aleadam - 這有什麼關係嗎? OP要求提供信息......不是代碼。 – 2011-04-06 05:13:21

+0

@Stephen是的,但很容易找到信息,可以在任何書的第一章找到,這就是爲什麼我問。 – Aleadam 2011-04-06 05:17:55

+0

你想說相同的簽名或只是方法的名稱?這使很多不同 – Ravisha 2011-04-06 06:58:05

回答

2

只有當它們的參數聲明與內存不同時。

27

只,如果他們接受不同的參數。如果沒有參數,那麼你必須有不同的名字。

int doSomething(String s); 
String doSomething(int); // this is fine 


int doSomething(String s); 
String doSomething(String s); // this is not 
+1

不僅。 int doSomething(string)和String dosomething(String)具有不同的返回類型,所以Java Bytecode中的簽名也是不同的,所以它是允許的。要調用此方法,您必須使用反射或字節碼。 – barwnikk 2015-08-29 06:27:55

+0

@barwnikk:當然,但是返回類型與它沒有任何關係 - 由於大小寫的不同,它們也有不同的名稱。 – Kaivosukeltaja 2015-08-30 12:11:56

+0

大寫字母差異是因爲我的換檔鍵壞了。 ;)可以使用相同的參數和方法名稱創建兩個方法,但只能使用不同的返回值。但是你會在Eclipse中遇到問題。當你調用方法時,你會得到錯誤,所以你必須使用字節碼。 ;)很多使用這個的混淆器。如果你知道字節碼,類名可以是「if」,「do」,「for」。 – barwnikk 2015-08-31 11:42:33

6

No. C++和Java都不允許在函數的返回類型上重載。原因是返回類型的重載可能會造成混淆(開發人員很難預測將調用哪個超載)。事實上,有些人認爲任何超載都會在這方面引起混淆並推薦反對,但即使那些贊成超載的人似乎也認同這種特殊形式太混亂。

+0

在Java(至少)中,兩種方法可以具有相同的名稱和不同的返回類型**提供**,它們也具有不同的參數類型;請參閱@ uthark的答案鏈接的JLS部分。 – 2011-04-06 05:10:08

+0

正確,但不是在返回類型上重載,即在參數類型上重載。而重載只是恰好有不同的返回類型(返回類型與超載完全無關)。 – 2011-04-07 23:01:50

69

如果兩種方法具有相同的參數類型,但不同的返回類型比不可能。從Java Language Specification, Java SE 8 Edition, §8.4.2. Method Signature

兩種方法或構造函數,M和N,具有相同的簽名,如果他們有相同的名字,相同類型的參數(如果有的話)(§8.4.4),並且,調整後正式N的參數類型爲M的類型參數,相同的形式參數類型。

如果兩種方法都有不同的參數類型(所以它們有不同的簽名),那麼這是可能的。它被稱爲超載。

+8

+1鏈接到規範......並且是正確和清晰的。 – 2011-04-06 05:10:56

+0

但爲什麼這會有用? – user3932000 2016-09-17 17:59:12

4

只有當其中一個方法被繼承並且返回類型兼容時,您纔可以擁有兩個具有相同參數和不同返回類型的方法。

例如:

public class A 
{ 
    Object foo() { return null; } 
} 

public class B 
    extends A 
{ 
    String foo() { return null; } 
} 
+1

的確,我今天早些時候才發現這一點。如果你調用'B.class.getDeclaredMethods()',你會看到它們都出現了。您可以通過反射調用任一版本。 – Kidburla 2015-11-05 16:11:01

18

根據JLS,但是你不能因爲在Java 6/7編譯器的特性/錯誤(Oracle的JDK,OpenJDK的,IBM的JDK),你可以有不同的返回類型如果您使用泛型,則使用相同的方法簽名。

public class Main { 
    public static void main(String... args) { 
     Main.<Integer>print(); 
     Main.<Short>print(); 
     Main.<Byte>print(); 
     Main.<Void>print(); 
    } 

    public static <T extends Integer> int print() { 
     System.out.println("here - Integer"); 
     return 0; 
    } 
    public static <T extends Short> short print() { 
     System.out.println("here - Short"); 
     return 0; 
    } 
    public static <T extends Byte> byte print() { 
     System.out.println("here - Byte"); 
     return 0; 
    } 
    public static <T extends Void> void print() { 
     System.out.println("here - Void"); 
    } 
} 

打印

here - Integer 
here - Short 
here - Byte 
here - Void 

有關詳細信息,read my article here

+2

JLS確實允許這4種方法,即使它們具有相同的返回類型。討論超載時實際上並沒有考慮返回類型(#8.4.2)。所以,按照當前的語言規範,這不是一個錯誤,以允許這4種方法。但是,如果javac具有相同的返回類型,則它們無法編譯它們 - *表示錯誤。這是對這個bug有罪的語言規範;他們沒有仔細考慮整個仿製藥的事情。 – irreputable 2011-04-06 07:47:37

+0

@irreputable,關於泛型的一致意見,這就是爲什麼我認爲如果這意味着設計被深思熟慮的話,關閉延遲可能是件好事。 ;)看看你需要做些什麼來創建一個泛型數組,或者使用double和triple轉換,或者甚至是java.util.ArrayList'不會在沒有警告的情況下編譯的事實(必須是最基本用例) – 2011-04-06 07:52:16

1

如果它在同級別與同等數量的參數與同類型和順序, 那麼它是不可能的例如:

int methoda(String a,int b) { 
     return b; 
} 
String methoda(String b,int c) { 
     return b;  
} 

如果數字的參數和它們的類型是相同的,但是順序是不同的,因此它可能會導致方法重載。這意味着方法簽名是否相同,其中包括方法名稱,其中包含參數數量及其類型以及它們定義的順序。

1

即使它是一個古老的線程,也許有些是有興趣的。

如果它是一個選項,您可以使用相同方法同一個類內部和存檔不同的返回類型,使用泛型:Oracle Lesson Generics

仿製值保持類的簡單例子:

class GenericValue<T> { 
    private T myValue; 

    public GenericValue(T myValue) { this.myValue = myValue; } 

    public T getVal() { return myValue; } 
} 

並使用它像這樣:

public class ExampleGenericValue { 
    public static void main(String[] args) { 
    GenericValue<Integer> intVal = new GenericValue<Integer>(10); 
    GenericValue<String> strVal = new GenericValue<String>("go on ..."); 

    System.out.format("I: %d\nS: %s\n", intVal.getVal(), strVal.getVal()); 
    } 
} 

...將導致以下輸出:

I: 10 
S: go on ... 
相關問題