2017-04-07 17 views
3

주어진 예제 코드는 total을 초기화하는 방법으로, 나중에 사용할 때 null 체크를하지 않아도됩니다. 나는 값을 생성자에 전달할 수 없다.널 체크를 피하기 위해 WeakReference 객체를 초기화하십시오.

public class SampleCode 
{ 

    private WeakReference<Float> total; 

    public SampleCode() { 
    } 

    public void setWidget(Float total) { 
     this.total = new WeakReference<>(total); 
    } 

    public float calculatePercentage(Float count) { 
     if (total == null) { 
      return -1; 
     } 
     if (total.get() == null) { 
      return -1; 
     } 

     return count/total.get(); 
    } 
} 
내가 생성자에서 같은 것을 할 싶습니다

:

this.total = new WeakReference<>(null); 

그러나 그것은 작동하지 않습니다. 출시 된 상태에서 WeakReference를 초기화 할 수 있습니까, 아니면 수업 목적에 어긋날까요?

감사

편집 모든 피드백에 대한

감사합니다.

  • float의 사용은 질문을 단순화하기위한 것이지만 혼란을 완전히 이해할 수 있습니다. 약한 참조가 실제로 보유하고있는 객체는 Android 레이아웃의 뷰이며이 클래스는 액티비티 라이프 사이클 외부에 존재합니다. this.total = new WeakReference<>(null); 로 초기화하는 후

total.get() == null false로 평가 :이

  • 문 "이 작동하지 않습니다"를 평가하기 전에
  • total.get()가 로컬 값을 할당해야하는 관계에 있었다 나는 그 진술이 부정확하다는 것을 이해한다. 이것은 사실로 평가 될 것입니다. 그러나 그것은 null로 초기화하지 않고 액세스하기 전에 null 조건을 확인하는 것이 더 좋을 것이라고 생각합니다.

  • +3

    ctor에서 초기화 할 때 작동하지 않는다는 것은 무엇을 의미합니까? –

    +0

    여기에 하나 이상의 질문을하는 것 같습니다. 하나는 null 검사를 피하는 것과 다른 하나는 null/해제 된 상태로 초기화하는 것입니다. –

    +2

    왜? WeakReference를 사용하는 이유는 무엇입니까? 왜 '플로트'를 사용해야하나요? 왜 '떠 다니는'것이 아니겠습니까? – EJP

    답변

    7

    이처럼 초기화 할 수 있습니다. 새로운 calculatePercentage 방법의
    예 : 그것은 WeakReference<Float>를 사용하는 매우 거의 의미가

    그러나
    public float calculatePercentage(Float count) { 
        Float totalF = total.get(); 
        if(totalF == null) 
         return -1; 
    
        return count/totalF; 
    } 
    

    ,
    대부분의 상황에서. 왜 그냥 프리미티브 float을 사용하지 않는가? 또는 실제로 Float 개체를 원한다면 왜냐하면 Float 객체는 언제 가비지 수집 될 것입니까? 일관성없는 상태로 만들고 버그를 추적하기 어려울 것이라고 생각합니다.

    +0

    WeakReference에서 실제 객체는 어디에 래핑됩니다. 나는 단지'new WeakReference <> (null) 만 보았고, –

    +0

    @ nits.kk는'WeakReference '를'total'에 할당함으로써 설정 될 것입니다. 질문에서 이것은'setWidget (Float total)'메쏘드에서 행해진 다. – RobCo

    +0

    옳습니다. 당신은 지금 upvote가 :) –

    5

    WeakReference을 사용하려면 반드시 사용 전에 null 확인을 확인해야합니다. 존재가 다른 문맥 상태에 의존하는 객체 A가 있다고 가정합니다.

    이러한 개체가 해당 상황에 대해 알 수없는 클래스에 전달되면 WeakReference 개체에 래핑 된 개체를 항상 전달하는 것이 좋습니다. 이러한 객체에 대한 강력한 참조 수가 0이되면 다음 가비지 수집기 사이클이 실행될 때 객체가 가비지 수집됩니다. 이 시점에서 WeakReference의 객체는 get()이 호출 될 때 null을 제공하기 시작합니다. 이것은 객체의 수명이 끝났음을 나타내는 문맥 상태에 대해 알지 못하는 클래스를 사용하는 신호입니다.

    사용하기 전에 (get()을 호출 한 후) 로컬 변수에 개체를 저장하고 null 검사를 확인한 다음 사용하는 것이 가장 좋습니다.

    weakReference.get()에 대한 조건에 대해 null이 아닌지 확인한 경우에도 다음 행을 null로 표시 할 수는 없습니다. 로컬 변수에 get()이 반환 한 객체를 저장하고 null이 아닌지 확인한 다음 사용해야합니다. 개체에 대한 강력한 참조가 만들어 지므로 개체 (예 : get())를 인스턴스로 저장하지 마십시오. 로컬 변수를 만들고 다른 로컬 변수를 전달하지 마십시오. 그곳에서 그걸 사용하고 그 범위가 끝나면 죽게하십시오.

    메서드 매개 변수로 WeakReference (new WeakReference<strongReferenceOfSomeObject>())의 개체를 사용하여 개체를 감싸고 전달할 수 있습니다.컨텍스트 상태 변경 (객체 수명을 결정할 수 있음)을 알지 못하는 클래스에 메서드 매개 변수 또는 생성자 매개 변수로 전달하면 인스턴스 변수에 할당하면 안됩니다. 인스턴스 변수에 할당해야하는 경우 WeakReference으로 저장해야합니다.

    은 참조하십시오 더 https://docs.oracle.com/javase/7/docs/api/java/lang/ref/WeakReference.html

    P.S.에서Float의 경우 float을 사용하고 Float의 포장 대상이 아니므로 WeakReference에 쉽게 해결할 수 있습니다. 문제의 코드에 WeakReference이 필요하지 않습니다. 위의 내 대답은 일반적으로 WeakReference 사용의 높은 수준의 기본 undertanding을 제공하는 것을 목표로합니다.

    private WeakReference<Float> total = new WeakReference<>(null); 
    

    지금의 기준 자체가 null이 될하지 않습니다,하지만 get 메소드는 null를 돌려 않습니다이다 :

    +0

    calculatePercentage()에 대한 호출간에 'total'이 다를 수있는 경우 OP 코드에 WeakReference가 필요할 수 있습니다. 그런 다음 calculatePercentage 메소드는 항상 total의 현재 값을 사용합니다. (그러나 그 경우, WeakReference는 사용하기에 적합한 것이 아니라 단지 단순한 참조라고 생각합니다.) –