클래스 인스턴스 메소드 NPE에 대한 Java 8 메소드 참조

mpsrig
import java.util.function.Function;

public class Playground {
    public static void main (String[] args) {
        Object o = null;
        System.out.println(o);
        Function<Object, String> toStringFunc = Object::toString;
        String s = toStringFunc.apply(o);
        System.out.println(s);
    }
}

이 코드는이 발생합니다 NullPointerException슬로우, 포함하는 행에서보고 toStringFunc.apply(o).

이것은 사소한 예제이므로 쉽게 알 수 o == null있지만 일반적으로이 코드 줄에서 NPE를 던지는 이유를 이해할 수 있습니다 toStringFunc. 해당 줄에서 역 참조되는 유일한 변수가 null이 아닙니다.

홀거

일반적으로 가장 깊은 스택 추적 항목을 살펴보고 해당 행에서 역 참조 된 변수를 찾습니다. 스택 추적이 다음과 같을 때 이것이 가능하지 않다는 점이 맞습니다.

Exception in thread "main" java.lang.NullPointerException
        at Playground.main(Playground.java:9)

문제는 main메서드 의이 줄에서 실제 역 참조가 발생하지 않았다는 것입니다. apply구현이 JRE 생성 클래스의 일부이고 스택 프레임이 추적에서 생략 된 호출 된 메소드 내에서 발생 합니다.

항상 그런 것은 아닙니다. JDK-8025636 : Hide lambda proxy frames in stacktraces 의 결과입니다 . 이 변경 사항은 이 Q & A 에서도 논의되었습니다 .

숨김은 람다 식에 대해 원활하게 작동합니다.

import java.util.function.Function;

public class Playground {
    public static void main (String[] args) {
        Object o = null;
        System.out.println(o);
        Function<Object, String> toStringFunc = obj -> obj.toString();
        String s = toStringFunc.apply(o);
        System.out.println(s);
    }
}

대신 스택 추적은 다음과 같습니다.

Exception in thread "main" java.lang.NullPointerException
        at Playground.lambda$main$0(Playground.java:8)
        at Playground.main(Playground.java:9)

호출자 ( main)와 피 호출자 ( ) 사이에 관련이없는 생성 된 메서드 lambda$main$0가 생략 된 상태에서 역 참조가 발생한 정확한 위치를 보여줍니다 .

안타깝게도 다른 가시적 인 메서드의 도움없이 대상 메서드가 직접 호출되는 메서드 참조에서는 원활하게 작동하지 않습니다. 이는 특히 호출 자체가 실패하여 대상 메서드가 추적에없는 경우 (예 : 수신자 인스턴스가) 인 경우에 역효과를 null냅니다. null대상 메서드를 호출하기 전이나 후에 생성 된 코드에서 unbox를 시도 할 때 유사한 문제가 발생할 수 있습니다 .

한 가지 해결책은
-XX:+UnlockDiagnosticVMOptions -XX:+ShowHiddenFrames스택 프레임 숨기기를 비활성화하는 옵션 으로 JVM을 실행하는 것 입니다. 이것은 리플렉션과 같은 다른 바인딩 코드에도 영향을 미치기 때문에 훨씬 더 긴 스택 추적을 유발할 수 있습니다. 따라서 특정 예외가보고 된 장소에서 발생하지 않고 숨겨진 프레임에서 발생했다고 의심되는 경우에만이 옵션을 사용할 수 있습니다. 이 옵션을 원래 코드와 함께 사용하면 다음이 생성됩니다.

Exception in thread "main" java.lang.NullPointerException
        at Playground$$Lambda$1/321001045.apply(<Unknown>:1000001)
        at Playground.main(Playground.java:9)

클래스 및 메서드의 이름은 다를 수 있지만 생성 된 코드로 인식 할 수 있습니다. 이 스택 추적에서 main9 행 에서 역 참조되는 변수가 아니라 호출에 전달 된 인수 중 하나가 여야 한다는 결론을 내릴 수 있습니다 null.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

자바에서 인스턴스 메소드 참조에 대해 forEach의 제한 (8)

분류에서Dev

인스턴스 인스턴스 메소드의 메소드 참조 VS 클래스 타입의 인스턴스 메소드의 메소드 레퍼런스

분류에서Dev

Java-Beanshell : 클래스 참조없이 Beanshell 내에서 메소드 실행

분류에서Dev

Mockito : 클래스의 모든 인스턴스에 대한 모의 인스턴스 메소드

분류에서Dev

Java 8에서 다차원 배열에 대한 메소드 참조

분류에서Dev

Eclipse Luna (R) : Java 8 메소드 참조에 대한 컨텐츠 지원 없음

분류에서Dev

중첩 된 클래스에서 메소드를 참조하는

분류에서Dev

java ... Object 클래스에서 equals 메소드 대체

분류에서Dev

클래스, 메서드에 대한 확인되지 않은 참조

분류에서Dev

클래스 java의 여러 메소드에 대한 단일 캐치 블록

분류에서Dev

익명 클래스의 정적 Java 메소드에 대한 Clojure 호출

분류에서Dev

Java-구현 클래스에 대한 인터페이스의 제한 메소드 매개 변수

분류에서Dev

Java 8 인스턴스 메서드 참조는 람다 호출과 동일합니까? 제 경우에는

분류에서Dev

java : 동일한 클래스에서 스레드 메소드 실행

분류에서Dev

여러 get 메소드에 대한 java8의 스트림 사용법

분류에서Dev

메소드간에 Java에서 동일한 객체 인스턴스 사용

분류에서Dev

메인 클래스에 대한 Bukkit 정적 참조

분류에서Dev

java.lang.NullPointerException : 다른 클래스 및 메소드의 인스턴스를 가져 오는 동안 널 오브젝트 참조에서 가상 메소드 호출 시도

분류에서Dev

Java 클래스에 대해 동일한 클래스의 메소드를 모의하는 방법을 Spock

분류에서Dev

Java 인스턴스 대 추상 클래스 및 메서드

분류에서Dev

메서드 / 클래스 참조 문제에서 멈춤 (JAVA Basic)

분류에서Dev

ProviderTestCase 하위 클래스에 대한 setUp () 메서드의 NPE

분류에서Dev

정적 메소드에 대한 Java 스레드 잠금

분류에서Dev

한 클래스에서 다른 클래스로 메서드 참조 시도 = NullPointerException

분류에서Dev

메인 또는 메소드를 통한 클래스 인스턴스화

분류에서Dev

Java에서 메소드에 대한 액세스를 제한하기위한 디자인 패턴

분류에서Dev

클래스 'bool'에는 인스턴스 메소드 '-'가 없습니다. 수신자 : 참 전화 시도 :-(거짓)

분류에서Dev

클래스 메소드에 대한 beginTransaction PDO

분류에서Dev

클래스의 메소드에 대한 EXC_BAD_ACCESS

Related 관련 기사

  1. 1

    자바에서 인스턴스 메소드 참조에 대해 forEach의 제한 (8)

  2. 2

    인스턴스 인스턴스 메소드의 메소드 참조 VS 클래스 타입의 인스턴스 메소드의 메소드 레퍼런스

  3. 3

    Java-Beanshell : 클래스 참조없이 Beanshell 내에서 메소드 실행

  4. 4

    Mockito : 클래스의 모든 인스턴스에 대한 모의 인스턴스 메소드

  5. 5

    Java 8에서 다차원 배열에 대한 메소드 참조

  6. 6

    Eclipse Luna (R) : Java 8 메소드 참조에 대한 컨텐츠 지원 없음

  7. 7

    중첩 된 클래스에서 메소드를 참조하는

  8. 8

    java ... Object 클래스에서 equals 메소드 대체

  9. 9

    클래스, 메서드에 대한 확인되지 않은 참조

  10. 10

    클래스 java의 여러 메소드에 대한 단일 캐치 블록

  11. 11

    익명 클래스의 정적 Java 메소드에 대한 Clojure 호출

  12. 12

    Java-구현 클래스에 대한 인터페이스의 제한 메소드 매개 변수

  13. 13

    Java 8 인스턴스 메서드 참조는 람다 호출과 동일합니까? 제 경우에는

  14. 14

    java : 동일한 클래스에서 스레드 메소드 실행

  15. 15

    여러 get 메소드에 대한 java8의 스트림 사용법

  16. 16

    메소드간에 Java에서 동일한 객체 인스턴스 사용

  17. 17

    메인 클래스에 대한 Bukkit 정적 참조

  18. 18

    java.lang.NullPointerException : 다른 클래스 및 메소드의 인스턴스를 가져 오는 동안 널 오브젝트 참조에서 가상 메소드 호출 시도

  19. 19

    Java 클래스에 대해 동일한 클래스의 메소드를 모의하는 방법을 Spock

  20. 20

    Java 인스턴스 대 추상 클래스 및 메서드

  21. 21

    메서드 / 클래스 참조 문제에서 멈춤 (JAVA Basic)

  22. 22

    ProviderTestCase 하위 클래스에 대한 setUp () 메서드의 NPE

  23. 23

    정적 메소드에 대한 Java 스레드 잠금

  24. 24

    한 클래스에서 다른 클래스로 메서드 참조 시도 = NullPointerException

  25. 25

    메인 또는 메소드를 통한 클래스 인스턴스화

  26. 26

    Java에서 메소드에 대한 액세스를 제한하기위한 디자인 패턴

  27. 27

    클래스 'bool'에는 인스턴스 메소드 '-'가 없습니다. 수신자 : 참 전화 시도 :-(거짓)

  28. 28

    클래스 메소드에 대한 beginTransaction PDO

  29. 29

    클래스의 메소드에 대한 EXC_BAD_ACCESS

뜨겁다태그

보관