자바 반사 파괴 방지 단일 모드

3601 단어 배 움 의 길
우 리 는 모두 하나의 사례 모델 이 하나의 인 스 턴 스 만 만 들 기 위 한 것 이라는 것 을 알 고 있 습 니 다. 그러나 자바 의 반사 체 제 는 이러한 단일 모델 을 파괴 할 수 있 습 니 다. 이런 반 사 를 통 해 단일 사례 를 파괴 하 는 예 는 인터넷 에 많 습 니 다. 나 는 열거 하지 않 겠 습 니 다. 오늘 우 리 는 자바 의 반사 체 제 를 사용 하여 단일 사례 를 파괴 하 는 것 을 어떻게 방지 하 는 지 말 합 니 다.인터넷 에서 많은 것 을 찾 아 보 았 습 니 다. 단일 사례 의 클래스 에 boolean 형식의 flag 를 추가 한 다음 에 구조 함수 에서 flag 의 값 을 바 꾼 다음 에 구조 함 수 를 호출 할 때 이 flag 가 이미 바 뀌 었 는 지 판단 합 니 다. 이렇게 하면 중복 생 성 대상 인 스 턴 스 를 방지 할 수 있 습 니 다. 이런 해결 방법 을 볼 때 이런 방법 이 엄밀 하지 않다 고 생각 합 니 다.반 사 를 통 해 구조 함 수 를 가 져 와 인 스 턴 스 를 만 들 수 있 기 때문에 반 사 를 통 해 정 의 된 flag 를 얻 을 수 있 습 니 다. 그러면 반사 호출 구조 함 수 를 이용 하기 전에 이 flag 를 가 져 온 다음 에 값 을 리 셋 하면 구조 함 수 를 다시 호출 하 는 데 제한 을 받 지 않 습 니 다.그러면 실제로 중복 생 성 을 방지 하 는 효과 가 없다.그래서 나 는 내 가 생각 한 다음 과 같은 방법 을 사용 했다.
public class SingletonClass {
//    private static final Boolean flag = Boolean.FALSE;
    private static ImmutableBoolean flag = new ImmutableBoolean();
    private SingletonClass() {
        if (flag.getCount() <= 0) {
            synchronized (SingletonClass.class) {
                if (flag.getCount() <= 0) {
                    flag.setCount();
                } else {
                    throw new RuntimeException("        1");
                }
            }
        } else {
            throw new RuntimeException("        2");
        }
    }
    private static SingletonClass singletonClass = null;

    public static SingletonClass getInstance() {
        if (singletonClass == null) {
            synchronized (SingletonClass.class) {
                if (singletonClass == null) {
                    singletonClass = new SingletonClass();
                }
            }
        }
        return singletonClass;
    }

    private static class ImmutableBoolean {
        private static int count = 0;
        public ImmutableBoolean() {

        }

        public void setCount() {
            synchronized (SingletonClass.class) {
                if (count <= 0) {
                    count ++;
                } else {
                    throw new RuntimeException("");
                }
            }
        }

        public int getCount(){
            return count;
        }
    }
}
public class TestClass {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        SingletonClass s1 = SingletonClass.getInstance();
//        System.out.println(s1);

        Class c1 = SingletonClass.class;
//        s1.new ImmutableBoolean();
//        SingletonClass.ImmutableBoolean
//        Field[] fields = c1.getDeclaredFields();
//        for (Field field : fields) {
//            System.out.println(field.getName());
//            if ("flag".equals(field.getName())) {
//                field.setAccessible(true);
//                Class c2 = field.getClass();
//                System.out.println(c2.getName());
////                Class c3 = field.
////                System.out.println(c3.getName());
////                field.
////                field.setBoolean(s1, false);
////                break;
//            }
//        }

        Constructor constructor = c1.getDeclaredConstructor();
        constructor.setAccessible(true);
        SingletonClass s2 = constructor.newInstance();
        System.out.println(s1 == s2);
    }
}

저 는 개인 적 인 내부 류 를 정의 한 다음 에 이 내부 류 의 속성 으로 flag 를 사용 합 니 다. 그러면 바깥 의 다른 류 는 이 개인 적 인 내부 류 를 얻 지 못 하고 그 값 을 바 꾸 지 못 해서 단일 사례 의 실현 을 보호 합 니 다.

좋은 웹페이지 즐겨찾기