programing

Java에서 정적 메서드에서 getClass()를 호출하려면 어떻게 해야 합니까?

goodcopy 2022. 7. 24. 23:34
반응형

Java에서 정적 메서드에서 getClass()를 호출하려면 어떻게 해야 합니까?

정적 메서드를 사용해야 하는 클래스가 있습니다.이러한 스태틱 메서드에서는 다음 콜을 발신하기 위해 메서드 getClass()를 호출해야 합니다.

public static void startMusic() {
  URL songPath = getClass().getClassLoader().getResource("background.midi");
}

하지만 이클립스는 말한다:

Cannot make a static reference to the non-static method getClass() 
from the type Object

이 컴파일 시간 오류를 수정하는 적절한 방법은 무엇입니까?

정답

쓰세요.TheClassName.classgetClass().

로거 선언

로그 선언을 쉽게 삽입할 수 있도록 특정 사용 사례에 대한 관심이 매우 높기 때문에 이에 대한 의견을 덧붙여야겠다고 생각했습니다.로그 프레임워크에서는 로그가 특정 컨텍스트(예: 완전 수식 클래스 이름)로 제한될 것으로 예상하는 경우가 많습니다.따라서 수정 없이 복사 붙여넣기가 불가능합니다.안전한 로그 선언 붙여넣기에 대한 제안은 다른 답변에서 제공되지만 바이트 코드를 부풀리거나 런타임 검사 추가와 같은 단점이 있습니다.이건 추천하지 않습니다.복사 붙여넣기는 편집자의 문제이므로 편집자 솔루션이 가장 적합합니다.

IntelliJ에서는 라이브 템플릿을 추가할 것을 권장합니다.

  • 약자로 "log" 사용
  • private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger($CLASS$.class);이치노
  • [(Edit Variables)]를하여 CLASS를 합니다(CLASS).className()
  • FQ 이름을 다시 포맷하고 단축하려면 이 상자를 선택합니다.
  • 컨텍스트를 Java: 선언으로 변경합니다.

, 이제 '우리'를요.log<tab>

private static final Logger logger = LoggerFactory.getLogger(ClassName.class);

Import를 자동으로 재포맷하고 최적화할 수 있습니다.

는, 그 으로 명시적으로 으로, 「」 「」 「반드시」 「반드시」 「반드시」 「반드시」 「반드시」가 필요 없습니다.getClassLoader() 삭제:

class MyClass {
  public static void startMusic() {
    URL songPath = MyClass.class.getResource("background.midi");
  }
}

이 방법에는 여전히 이 코드를 여러 유사한 클래스에 복제해야 하는 경우 복사/붙여넣기 오류로부터 매우 안전하지 않다는 단점이 있습니다.

그리고 헤드라인의 정확한 질문에 대해서는, 다음의 스레드에 트릭이 게재되어 있습니다.

Class currentClass = new Object() { }.getClass().getEnclosingClass();

어나니머스 어나니머스 어나니머스 어나니머스 어나니머스 어나니머스 어나니머스 어나니머스 어나니머스를 사용합니다.Object를 사용하여 subclass를 가져옵니다.이 트릭은 복사/붙여넣기가 안전하다는 장점이 있습니다.

다른 클래스가 상속받는 기본 클래스에서 이 클래스를 사용할 때 주의:

이 어떤 로 형성되어 는, 「」라고 하는 해 주세요.currentClass값은 항상 해당 메서드를 사용할 수 있는 하위 클래스가 아니라 해당 기본 클래스에 대한 참조가 됩니다.

Java7+ 에서는, 이것을 스태틱한 메서드/필드에서 실행할 수 있습니다.

MethodHandles.lookup().lookupClass()

제가 직접 씨름했어요.좋은 방법은 정적 컨텍스트에서 현재 스레드를 사용하여 ClassLoader를 얻는 것입니다.이것은 Hadoop MapReduce에서도 작동합니다.다른 메서드는 로컬에서 실행할 때는 작동하지만 MapReduce에서 사용할 때는 null InputStream을 반환합니다.

public static InputStream getResource(String resource) throws Exception {
   ClassLoader cl = Thread.currentThread().getContextClassLoader();
   InputStream is = cl.getResourceAsStream(resource);
   return is;
}

클래스 리터럴을 사용하면 됩니다.NameOfClass.class

먹어봐.

Thread.currentThread().getStackTrace()[1].getClassName()

또는

Thread.currentThread().getStackTrace()[2].getClassName()

getClass()method는 오브젝트클래스에서 다음 시그니처를 사용하여 정의됩니다.

public final Class get Class()

라고 정의되어 있지 않기 때문에static정적 코드 블록 내에서는 호출할 수 없습니다.상세한 것에 대하여는, Q1, Q2, Q3 의 회답을 참조해 주세요.

정적 컨텍스트의 경우 클래스 리터럴식을 사용하여 클래스를 가져와야 합니다.따라서 기본적으로 다음과 같이 해야 합니다.

푸클래스

이러한 유형의 표현은 클래스 리터럴이라고 불리며 Java Language Specification Book에서 다음과 같이 설명합니다.

클래스 리터럴은 클래스 이름, 인터페이스, 배열 또는 원시 유형 뒤에 '.'와 토큰 클래스가 이어지는 표현식입니다.클래스 리터럴의 유형은 클래스입니다.현재 인스턴스의 클래스를 정의하는 클래스 로더에 의해 정의된 명명된 유형(또는 비활성)에 대한 Class 객체에 대해 평가됩니다.

이 주제에 대한 정보는 클래스의 API 문서에서도 찾을 수 있습니다.

나도 같은 문제가 있었어! 하지만 해결하려면 네 코드를 다음과 같이 수정해.

public static void startMusic() {
URL songPath = YouClassName.class.getClassLoader().getResource("background.midi");
}

이게 잘 먹혔으면 좋겠어요.

유틸리티 클래스가 있다고 가정하면 샘플 코드는 다음과 같습니다.

    URL url = Utility.class.getClassLoader().getResource("customLocation/".concat("abc.txt"));

CustomLocation - 리소스 내에 폴더 구조가 있는 경우 이 문자열 리터럴을 제거합니다.

이런 거 해봐.저는 좋아요.로그(클래스명)

    String level= "";

    Properties prop = new Properties();

    InputStream in =
            Logg.class.getResourceAsStream("resources\\config");

    if (in != null) {
        prop.load(in);
    } else {
        throw new FileNotFoundException("property file '" + in + "' not found in the classpath");
    }

    level = prop.getProperty("Level");

언급URL : https://stackoverflow.com/questions/8275499/how-to-call-getclass-from-a-static-method-in-java

반응형