한 편의 글 은 자바 단일 모드 를 실현 하기 위해 매 거 진 을 사용 하 는 것 을 가 르 칩 니 다.
우선,대부분의 경우(면접 포함 되 지 않 음)전통 적 인 단일 표기 법 은 이미 충분히 사용 할 수 있다.synchronized 키 워드 를 통 해 다 중 스 레 드 병행 사용 을 해결 하 였 습 니 다.
public synchronized static SingleClassV1 getInstance(){
if(instance == null){
instance = new SingleClassV1();
}
return instance;
}
매번 단일 대상 을 가 져 올 때마다 자 물 쇠 를 추가 하고 자 물 쇠 를 풀 어야 한 다 는 것 을 고려 합 니 다.또 누군가가 이중 잠 금 검사+volatile 키워드 모드 를 발명 했다.
private static volatile SingleClassV2 instance;
public static SingletonV2 getInstance() {
if(instance == null){
synchronized (SingletonV2.class){
if(instance == null){
instance = new SingletonV2();
}
}
}
return instance;
}
또 하나의 사례 가 중복 되 고 초기 화 되 는 것 을 해결 하기 위 한 쓰기:클래스 를 이용 하면 한 번 만 초기 화 되 는 특성 을 이용 하여 내부 사례 의 쓰기 도 발명 되 었 다.
private static class SingletonHolder {
private static final SingletonV3 INSTANCE = new SingletonV3();
}
public static final SingletonV3 getInstance() {
return SingletonHolder.INSTANCE;
}
여전히 존재 하 는 문제자바 에는 반사 API 라 는 변태 가 존재 하기 때문에 상기 모든 사유 구조 방법 은 반사 앞에서 모두 이슬비 이다.
Class<?> clazzV2 = Class.forName(SingleClassV2.class.getName());
Constructor<?> constructor = clazzV2.getDeclaredConstructors()[0];
constructor.setAccessible(true);
Object o = constructor.newInstance();
보아하니 사유 방법 은 군 자 를 막 고 소인 을 막 지 않 는 것 같다.왜 매 거 하면 문제 가 없 습 니까?
매 거 에 기초 한 단일 사례 가 어떤 지 먼저 살 펴 보 자.
public enum SingleClassV4 {
INSTANCE;
public String doSomeThing(){
return "hello world";
}
}
물론 자바 코드 에 서 는 어떤 단서 도 찾 아 볼 수 없습니다.자바 p 를 사용 하여 바이트 코드 를 보 세 요.
public final class git.frank.SingleClassV4 extends java.lang.Enum<git.frank.SingleClassV4>
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
매 거 진 유형 은 자바.lang.Enum 류 를 자동 으로 계승 하 는 데 도움 을 줄 수 있 습 니 다.또한,flags 에 이 종 류 는 ACC 가 추가 되 었 습 니 다.ENUM 표식.그리고 매 거 류 의 구조 방법 을 살 펴 보 자.
private git.frank.SingleClassV4();
descriptor: (Ljava/lang/String;I)V
flags: ACC_PRIVATE
Code:
stack=3, locals=3, args_size=3
0: aload_0
1: aload_1
2: iload_2
3: invokespecial #6
// Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
6: return
LineNumberTable:
line 3: 0// Java :756584822
LocalVariableTable:
Start Length Slot Name Signature
0 7 0 this Lgit/frank/SingleClassV4;
Signature: #29 // ()V
매 거 류 도 구조 방법 이 있어 야 하고 일반 류 와 다 르 지 않 으 며 반 사 를 통 해 얻 을 수 있다.다음은 반사 invoke 를 통 해 그의 구조 방법 을 살 펴 보 자.
constructor.newInstance();
결 과 는 다음 과 같다.Exception in thread "main" java.lang.IllegalArgumentException: Cannot reflectively create enum objects at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
new Instance 방법 코드 를 보면 이 유 를 쉽게 알 수 있 습 니 다.
public T newInstance(Object ... initargs)
throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException
{// Java :756584822
...
if ((clazz.getModifiers() & Modifier.ENUM) != 0)
throw new IllegalArgumentException("Cannot reflectively create enum objects");
...
T inst = (T) ca.newInstance(initargs);
return inst;
}
자바 의 반사 API 는 생 성 대상 인 스 턴 스 에서 현재 클래스 가 매 거 진 형식 인지 아 닌 지 를 판단 합 니 다.그렇지 않 으 면 이상 을 던 집 니 다.총결산
전통 적 인 사례 쓰기 에서 사유 구조 방법 은 외부 에서 인 스 턴 스 를 만 드 는 것 을 완전히 막 을 수 없 기 때문에 엄 밀 히 말 하면 그 사례 의 실현 방식 에 구멍 이 존재 한다.
자바 의 반사 API 는 이미 죽음 을 쓰 는 방식 으로 매 거 진 형식 에 인 스 턴 스 를 만 들 수 없 도록 제한 되 었 기 때문에...됐 습 니 다.해결 되 었 습 니 다.아이고,이 물건 도 면접 에서 물 어 본 거 야.정상 인 이 누가 반사 라 는 걸 로 단 례 를 돌파 하 겠 어.
이 글 은 여기까지 입 니 다.당신 에 게 도움 을 줄 수 있 기 를 바 랍 니 다.또한 당신 이 우리 의 더 많은 내용 에 관심 을 가 져 주 실 수 있 기 를 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.