2011-04-06 2 views
71

두 가지 Java 메소드가 같은 이름반환 유형을 가질 수 있습니까? 메소드의 리턴 유형은 다르며 동일한 메소드 이름으로 선언됩니다.두 개의 Java 메소드가 서로 다른 리턴 유형을 갖는 동일한 이름을 가질 수 있습니까?

허용 되나요?

+10

@Aleadam - 중요합니까? OP는 코드가 아니라 정보를 요구하고 있습니다. –

+0

@Stephen 그렇습니다. 그러나 어떤 책의 첫 번째 장에서 찾을 수있는 정보를 찾기가 매우 쉽습니다. 그래서 제가 묻고있는 것입니다. – Aleadam

+0

동일한 서명 또는 메서드 이름 만 말하려고합니까? 이것은 많은 차이를 만듭니다. – Ravisha

답변

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 바이트 코드의 서명도 다르기 때문에 허용됩니다. 이 메서드를 호출하려면 리플렉션 또는 바이트 코드를 사용해야합니다. – barwnikk

+0

@barwnikk : 물론 반환 유형은 아무 것도하지 않습니다. 대문자 사용의 차이로 인해 이름이 다릅니다. – Kaivosukeltaja

+0

내 시프트 키가 깨져서 대문자로 된 차이가 있습니다. ;) 당신은 같은 args와 메소드 이름을 가진 두 개의 메소드를 만들 수 있지만, 다른 반환 값만을 사용할 수 있습니다. 그러나 Eclipse에서 문제가 발생합니다. 메소드를 호출하면 오류가 발생하므로 바이트 코드를 사용해야합니다. ;) 이것을 사용하는 많은 obfuscator. 클래스 이름은 바이트 코드를 알고있는 경우 "if", "do", "for"일 수 있습니다. – barwnikk

6

아니요. C++과 Java는 모두 함수의 반환 형식에서 오버로드를 허용하지 않습니다. 그 이유는 반환 유형에 대한 오버로드가 혼동을 일으킬 수 있기 때문입니다 (개발자가 어떤 과부하를 호출 할 지 예측하기 어려울 수 있습니다). 사실 과부하는이 점에서 혼란스럽고 추천 할 만하다고 주장하는 사람들이 있습니다. 그러나 과부하를 선호하는 사람조차도이 특별한 형태가 너무 혼란 스럽다는 데 동의하는 것처럼 보입니다.

+0

Java에서 (적어도) 두 개의 메소드는 동일한 이름을 가질 수 있으며 서로 다른 리턴 유형을 가질 수 있습니다 ** ** 그들은 서로 다른 인수 유형을가집니다. @ uthark의 대답으로 연결된 JLS 섹션을보십시오. –

+0

맞아요,하지만 그것은 리턴 타입에서 오버로딩되지 않습니다. 이것은 매개 변수 유형에서 오버로딩됩니다. 그리고 과부하는 단순히 다른 반환 유형 (반환 유형은 완전히 과부하와 관련이 없습니다)을 갖습니다. –

69

두 메소드 모두 동일한 매개 변수 유형이지만 다른 리턴 유형을 사용할 수없는 경우. Java Language Specification, Java SE 8 Edition, §8.4.2. Method Signature에서 : 이름이 같은 경우

두 가지 방법 또는 생성자, M과 N이 같은 서명이, 동일한 유형의 매개 변수 (있는 경우) (§8.4.4), 그리고 공식을 적응 후 N의 매개 변수 유형은 동일한 형식 매개 변수 유형 인 M의 유형 매개 변수에 적용됩니다.

두 메서드의 매개 변수 유형이 서로 다른 경우 (서로 다른 서명이있는 경우) 가능합니다. 오버로드라고합니다.

+8

+1 사양에 연결하고 정확하고 명확합니다. –

+0

그러나 이것이 왜 유용할까요? – user3932000

4

메소드 중 하나가 리턴되고 리턴 유형이 호환 가능한 경우에만 동일한 인수와 다른 리턴 유형을 갖는 두 개의 메소드를 가질 수 있습니다.

예를 들어

:

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

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

사실, 방금 전에 이것을 발견했습니다. 'B.class.getDeclaredMethods()'를 호출하면 두 클래스 모두 나타납니다. 리플렉션을 통해 두 버전 중 하나를 호출 할 수 있습니다. – Kidburla

18

JLS에 따르면, 당신은 때문에 자바 6/7 컴파일러의 기능/버그 (오라클의 JDK, 오픈 JDK, 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는 리턴 타입이 같은 경우에는 컴파일 할 수 없습니다. *는 * 버그입니다. 이것은 버그에 대해 유죄 인 언어 스펙입니다. 그들은 제네릭 전체를 매우 신중하게 생각하지 않았습니다. – irreputable

+0

@irreputable 제네릭에 대해 동의했기 때문에 이것이 클로저의 지연은 디자인이 잘 고려되었다는 것을 의미한다면 좋은 것이라는 생각이 들었습니다. ;) 제네릭의 배열이나 double과 triple 캐스트의 사용, 또는'java.util.ArrayList'조차도 경고없이 컴파일하지 않는다는 사실을보기 위해 무엇을해야하는지 살펴 보라. 사용 사례의 기초) –

1

이 다음이 가능하지 않습니다 예 :

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

매개 변수와 해당 유형이 동일하지만 순서가 다르면 메서드 오버로드가 발생할 수 있으므로 가능합니다. 매개 변수 개수와 유형 및 메소드가 정의 된 순서가 포함 된 메소드 이름을 포함하는 메소드 서명이 동일한 경우를 의미합니다.

2

자바 문서 상태 :

방법을 차별화 때 그들은 다른 반환 형식을 경우에도 동일한 서명을 가진 두 가지 방법을 선언 할 수 있도록 컴파일러는, 반환 형식을 고려하지 않습니다.

참조 : 그것은 오래된 스레드하더라도 http://docs.oracle.com/javase/tutorial/java/javaOO/methods.html

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 ... 
관련 문제