나는 정적 값의 위험한 초기화가있는 라이브러리를 사용하고 있습니다 (예 : 클래스가 최소값으로 제거되었습니다) :은 FindBugs 'JLM_JSR166_UTILCONCURRENT_MONITORENTER'이 경우 안전합니다.
public TheirBaseClass {
public static String PathToUse = null;
public BaseClass(){
PathToUse = "Configured";
// ...
// do some other stuff with other side effects
// ...
}
}
값을 ConfigValue
(일부 부작용을 피하기 위해)을 인스턴스화하지 않고 읽으려는 경우가 있습니다.
Paths.get(TheirBaseClass.PathToUse).toFile()....
이 정적에 액세스 할 때 나는이 클래스를 사용하는 데 필요한하고 있기 때문에, 나는 그것에서 상속, 그 초기화를 보장하는 조치를 취하려고 찾고 오전 NullPointerException
이 자리를 차지하게됩니다.
MyBaseClass.Initialize();
Paths.get(MyBaseClass.PathToUse).toFile()....
날 수 있습니다
public MyBaseClass extends TheirBaseClass{
private static final AtomicBoolean isInitialized = new AtomicBoolean(false);
static {
MyBaseClass.Initialize();
}
public static void Initialize(){
// FindBugs does not like me synchronizing on a concurrent object
synchronized(isInitialized){
if(isInitialized.get()){
return;
}
new TheirBaseClass();
isInitialized.set(true);
}
}
public MyBaseClass(){
super();
}
}
이 합리적으로 잘 작동하는 것 같군 (우리가 꾸게 다른 팬텀 결함을 해결합니다). 그것은 TheirBaseClass
이 자연스럽게 작동 할 수있게 해주는 반면, 내가 필요로하는 몇 가지 경우에 초기화를 안전하게 할 수있게 해줍니다.
그러나이 코드에 대해 FindBugs를 실행하면 JLM_JSR166_UTILCONCURRENT_MONITORENTER
이됩니다. 설명을 읽은 후, 나는
- 내가이 경우에 무시의 안전을 생각한다 (그러나 의심의 여지가) ... 다른 사람이 값을 변경할 수 있기 때문에
AtomicBoolean
의 사용은 위험 할 수 있다고 동의하지만, - 나는 일반적으로
가 실제로 위험한 일을하고 있습니까 (및 단지 그것을 볼 수 없습니다) 대신에 무시 마커를 넣어보다 코드를 다시 작성하는 것을 선호? 이 작업을 수행하는 더 좋은 방법이 있습니까?
불행히도 다른 TheirBaseClass
을 사용하는 것은 옵션이 아닙니다.
당신은 쉽게 적응 찾을 수 있습니다
필자는 나의 예에서 큰 실수를 저질렀다고 생각한다. 나는 그들의베이스 클래스를 확장하지 않았다. –
나는 이것을 숙고해야만했다. 이미'게으른 홀더'를 구현하고 있습니다. 귀하의 대답은 정확하지만, 그 혼동은 부울 주위에서 발생하는 것 같습니다 : 그것은 완전히 불필요합니다. 특정 케이스에 대해 소개했지만이 경우 점점 더 많은 리팩토링을 수행 한 것으로 보입니다. –
부울은 불필요합니다. * 이니셜 라이저를 비공개로 만들면 * –