2011-01-13 11 views
6

Java의 리플렉션을 가지고 놀고 있습니다. 나는 추상적 인 클래스 Base을 생성자와 함께 가진다.리플렉션을 사용하여 추상 기본 클래스에서 생성자에 액세스

abstract class Base { 
    public Base(String foo) { 
     // do some magic 
    } 
} 

나는 추가 클래스가 Base까지 확장되어 있습니다. 그들은 많은 논리를 포함하지 않습니다. Base의 생성자로 인스턴스를 만들고 싶습니다. 파생 클래스에 프록시 생성자를 작성하지 않아도됩니다. 물론 Reflection을 사용하여 파생 클래스를 인스턴스화하려고합니다. 말 :

Class cls = SomeDerivedClass.class; 
Constructor constr; 
constr = cls.getConstructor(new Class[] { String.class }); // will return null 
Class clsBase = Base.class; 
constr = clsBase.getConstructor(new Class[] { String.class }); // ok 
Base obj = (Base) constr.newInstance(new Object[] { "foo" }); // will throw InstantiationException because it belongs to an abstract class 

아이디어, 어떻게 Base 's 생성자를 사용하여 파생 클래스를 인스턴스화 할 수 있습니까? 아니면 그 벙어리 프록시 생성자를 선언해야합니까?

+0

수업을 시작하기 전에 모든 것이 컴파일되고 있습니까? – gabuzo

+0

예, 정상적으로 컴파일됩니다. 이것은 단순한 예이며 catch 절이 없지만 기본적으로이 코드는 정상적으로 컴파일됩니다. 아, 그리고'Base'는 빈 기본 생성자를 추가로 가지고 있습니다 (javac이 주장했습니다). – craesh

답변

9

클래스는 부모로부터 생성자를 상속받지 않습니다. 클래스에는 부모 생성자가 없습니다 (호출 할 수는 있지만). 따라서 클래스에있는 생성자를 호출해야하며 수퍼 클래스에는 생성자가 없습니다.

기본 생성자는 기본적으로 부모의 기본 생성자를 호출하기 때문에이 작업을 수행하는 것으로 나타납니다. 부모가 디폴트 생성자를 가지지 않으면, 그 직접적인 자식도 생성 할 수 없다.

+0

가장 정확한 답변이기 때문에 답변을 수락했습니다. – craesh

1

기본 클래스 생성자가 기본값이 아니거나 (매개 변수가 있음) 문제가 있습니다. 따라서 생성 된 기본 하위 클래스 생성자에서 암시 적으로 호출 할 수 없습니다. (사실 당신은 컴파일 경고/이것에 대한 오류가 나타납니다.) 명시 적으로 하위 클래스 생성자를 추가해야 할까 봐 걱정됩니다.

+0

경고를받지 못했습니다. 어쩌면'Base'와 파생 클래스가 다른 Eclipse 프로젝트에있는 다른 패키지에 있기 때문일 수도 있습니다. – craesh

2

super() 생성자 중 하나를 호출하는 명시 적 생성자가있을 때까지 하위 클래스가 컴파일되지 않을까 걱정됩니다.

+0

모든 것이 잘 컴파일됩니다. 'Base (String)'은 어떤 서브 클래스에서도 호출되지 않습니다. 그러나'Base '에 대해 빈 기본 생성자를 한 번 정의해야했습니다. – craesh

+0

그것은 결정적인 차이입니다. 이것은 자식 클래스가 ans를 인스턴스화하지만 빈 부모 생성자 만 호출한다는 것을 의미합니다. 자식 클래스가 생성자에서 명시 적으로 호출하지 않는 한 다른 생성자에 액세스 할 수있는 방법은 없습니다. – biziclop

2

"비 추상적"이 될 세부 정보를 모두 지정하지 않고는 추상 클래스를 구성 할 수 없습니다. 부모 - 전용 클래스를 반환 반사 통해 조작 생성자에는 양

public abstract class Parent { 
    String name; 

    public Parent(String name) { 
    this.name = name; 
    } 

    abstract public String getName(); 

} 

: 예에 의미

. 당신은 그러나,과 같이, 건설 시간에 추상적 인 세부 사항을 지정하여 "익명"클래스를 반환 할 수 있습니다

Parent parent = new Parent() { 
    public String getName() { return "Bob"; } 
    }; 

당신의 코드를 삽입하지 않은 경우에도 하위 클래스라는 또한, 부모 생성자를 호출, 기억 명시 적으로.

public class Child extends Parent { 
    public Child(String name) { 
    } 
} 

Parent 클래스의 노 인수 생성자를 찾습니다 : 하위 클래스는 같은 기록. 명시 적으로 상위 클래스의 건설을 지정할 때까지 하나를 발견하는 경우가 Parent 클래스의 인수가없는 생성자를 찾을 수없는 경우, 다음은

public class Child extends Parent { 
    public Child(String name) { 
    super(); 
    } 
} 

해당하는 코드로 컴파일됩니다, 그것은 컴파일 실패 super(name); 생성자 호출

당신이 extends SomeClass과 같이 제공하지 않습니다, 그래서 만약 모든 클래스가 Object의 서브 클래스입니다 기억해야 할 또 다른 것은 :

:

public class JustMe { 
} 

컴파일러는 conceputally에 컴파일 시간에 당신이 코드를 "수정"

public class JustMe extends Object { 

    public JustMe() { 
    super(); 
    } 
} 

Object 클래스에는 JVM에 등록 할 원시 (Java 이외의) 코드 묶음이있어 올바른 가비지 수집, 메모리 관리, 유형 적용 등이 객체의 수명 기간 동안 유지되도록합니다.

즉. 주위를 둘러 볼 수는 없지만, 익명의 클래스 나 서브 클래스를 통해 메소드를 모두 해석 할 수 없다면 JVM은 생성 및 추상 클래스를 중단시킵니다.

+0

서브 클래스 화는 매개 변수가없는 상위 생성자 (존재하지 않는 경우)를 암시 적으로 호출하지 않습니다. 확실히 매개 변수를 전달하지 않습니다. 또한 추상 클래스의 생성자에 매개 변수가 필요한 경우 익명 클래스를 만들 때이 매개 변수를 지정해야합니다. 예를 들면 다음과 같습니다. new Parent ("foo") {...} – biziclop

+0

@biziclop 우수한 관찰, 후자를 위해 수정 된 게시물 –

+0

아직 최고의 답변. – milosmns

관련 문제