문제

추상 수업이 있습니다.

public abstract class AbstractAny {
  private long period;

  public void doSomething() {
    // blah blah blah
    period = someHardcodedValue;
    // blah blah blah
  }
}

나는 추상 클래스의 출처를 변경하고 싶지 않지만 필드 기간이 어떻게 설정되고 있는지에 대한 유연성을 추가해야합니다. 재정의 메소드에서 필드 기간의 값을 변경할 수 있습니까? 예를 들어 :

public class ConcreteSome extends AbstractAny{
  @Override
  public void doSomething() {
    try {
      Field p = super.getClass().getDeclaredField("period");
      p.setAccessible(true);
      p.setLong(this, 10L);
    } catch (SecurityException e) {
        throw new RuntimeException(e);
    } catch (NoSuchFieldException e) {
        throw new RuntimeException(e);
    } catch (IllegalArgumentException e) {
        throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
    }
  }
}

이 코드를 실행하려고 할 때 super.getClass().getDeclaredField("period") 던졌습니다 java.lang.NoSuchFieldException: period

도움이 되었습니까?

해결책

당신은 필요합니다 getClass().getSuperclass() 슈퍼 클래스를 얻기 위해 super.getClass().

그러나 나는 진짜 이 작업을 권장하지 마십시오. 당신은 기본적으로 추상 클래스의 캡슐화를 파괴하고 있습니다. 초록 클래스가 후손들에게 충분한 유연성을 제공하지 않으면 고쳐야합니다. 초록 클래스의 다른 구성원 이이 클래스를 변경할 때마다 변경해야한다면 어떨까요? 개인 상태를 갖는 요점은 클래스가 자체 데이터를 보호 할 수 있도록하는 것입니다. 이와 같은 반사를 사용하는 것은 정말 못생긴 해킹입니다. 마지막 의지.

다른 팁

저는 Jon Skeet과 함께 있습니다. 장기적으로 슈퍼 클래스의 소스 코드를 변경 하여이 필드를 보호하거나 돌연변이를 대체 가능한 방법으로 위임하는 것이 더 쉽습니다. 반사를 사용하여 값을 변경하는 것은 이제 잘 작동하지만 시간이 지남에 따라 유지 보수가 진행되는 한 크게 확장되지는 않습니다.

Concetesome은 추상 클래스 Abstractany를 확장하지 않습니다.
이 시도

public class ConcreteSome {
    @Override
    public void doSomething() {
        Class<?> clazz = getClass().getSuperclass();
        System.out.println(clazz);
        Field p = clazz.getDeclaredField("period");
        ...

java.lang.object를 반환해야합니다

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top