java 자이 - 비 정적 메서드에 대한 정적 참조를 만들 수 없습니다.




안드로이드 자바 (8)

비 정적 메소드에서 정적 변수를 참조 할 수 없습니다. 이를 이해하려면 정적 및 비 정적의 차이점을 이해해야합니다.

정적 변수는 클래스 변수이며, 오직 하나만 인스턴스가있는 클래스에 속하며 처음에만 생성됩니다. 비 정적 변수는 클래스의 객체를 만들 때마다 초기화됩니다.

이제 우리는 new () 연산자를 사용할 때 모든 객체에 대해 정적이 아닌 모든 파일의 복사본을 만들 것입니다. 그러나 정적 필드의 경우는 아닙니다. 따라서 정적이 아닌 메소드에서 정적 변수를 참조하는 경우 컴파일 시간 오류가 발생합니다.

Java로 다국어 애플리케이션 개발하기. R.string 리소스 XML 파일에서 문자열 값을 삽입 할 때 오류 발생 :

public static final String TTT =  (String) getText(R.string.TTT);

이것은 오류 메시지입니다.

오류 : Context 형식에서 비 정적 메서드 getText (int)에 대한 정적 참조를 만들 수 없습니다.

어떻게 이런 일이 생기고 어떻게 해결할 수 있습니까?


getText() 는 정적이 아니므로 정적 메서드에서 호출 할 수 없습니다.

이유를 이해하려면 두 가지의 차이점을 이해해야합니다.

인스턴스 (비 정적) 메소드는 특정 유형 (클래스) 인 오브젝트에 대해 작업합니다. 이것들은 다음과 같이 새로운 것으로 생성됩니다 :

SomeClass myObject = new SomeClass();

인스턴스 메소드를 호출하려면 인스턴스 ( myObject )에서 호출합니다.

myObject.getText(...)

그러나 정적 메서드 / 필드는 형식에 대해서만 직접 호출 할 수 있습니다. 예를 들면 다음과 같습니다. 이전 문이 올바르지 않습니다. myObject.staticMethod() 와 같은 객체 참조를 사용하여 정적 필드를 참조 할 수도 있지만 클래스 변수임을 명확하게 나타내지 않으므로 권장하지 않습니다.

... = SomeClass.final

둘은 서로 다른 데이터 공간 (인스턴스 데이터 및 클래스 데이터)에서 작동하므로 함께 작동 할 수 없습니다.

내가 해보고 설명하게 해줘. 이 클래스 (psuedocode)를 생각해보십시오 :

class Test {
     string somedata = "99";
     string getText() { return somedata; } 
     static string TTT = "0";
}

이제 다음 사용 사례가 있습니다.

Test item1 = new Test();
 item1.somedata = "200";

 Test item2 = new Test();

 Test.TTT = "1";

값은 무엇입니까?

in item1 TTT = 1 and somedata = 200
in item2 TTT = 1 and somedata = 99

즉, TTT 는 해당 유형의 모든 인스턴스가 공유하는 데이터입니다. 그래서 말하기에는 말이되지 않습니다.

class Test {
         string somedata = "99";
         string getText() { return somedata; } 
  static string TTT = getText(); // error there is is no somedata at this point 
}

그래서 질문은 TTT가 정적이거나 왜 왜 getText ()가 정적이 아닌가입니다.

static 제거하고이 오류를 지나쳐야합니다. 그러나 유형을 이해하지 못하면 다음 오류가 발생할 때까지 찌르는 석고 만 있습니다. 정적이 아닌 getText() 의 요구 사항은 무엇입니까?


비 정적 메소드를 사용하여 정적 변수를 초기화 할 수 없습니다.


변수를 정적이 아니게 만들 수도 있습니다

public final String TTT =  (String) getText(R.string.TTT);

또는 "getText"메소드를 정적으로 만들 수 있습니다 (가능한 경우).


이 질문은 새로운 것이 아니며 기존의 대답은 좋은 이론적 배경을 제공합니다. 나는 단지 좀 더 실용적인 대답을 덧붙이고 싶다.

getText는 Context 추상 클래스의 메소드이며이를 호출하기 위해서는 서브 클래스 (Activity, Service, Application 또는 기타)의 인스턴스가 필요합니다. 문제는 Context 인스턴스가 생성되기 전에 public static final 변수가 초기화된다는 것입니다.

이 문제를 해결할 수있는 몇 가지 방법이 있습니다.

  1. 정적 수정자를 제거하고 클래스 본문 내에 배치하여 변수를 컨텍스트의 Activity 또는 다른 하위 클래스의 멤버 변수 (필드)로 만듭니다.
  2. 정적으로 유지하고 초기화를 이후 시점으로 지연합니다 (예 : onCreate 메서드).
  3. 실제 사용 장소에 로컬 변수로 만듭니다.

검색에서 이것을 발견하는 다른 사람들을 위해 :

실수로 객체 이름 대신 클래스 이름을 사용하여 함수를 호출 할 때 종종이 객체를 가져옵니다. 이것은 내가 그들에게 너무 비슷한 이름을주기 때문에 일반적으로 발생합니다 : P

즉 :

MyClass myclass = new MyClass();

// then later

MyClass.someFunction();

이것은 분명히 정적 인 방법입니다. (좋은 일을 위해)하지만 내가 정말로하고 싶었던 (대부분의 경우)

myclass.someFunction();

그것은 어리석은 실수입니다. 그러나 매 2 개월마다, 저는 "MyClass"정의에있는 vars를 사용하는 데 약 30 분의 시간을 낭비합니다.

재미있는 메모 : 스택 오버플로는 여기에서 실수를 분명히하기 위해 구문을 강조 표시합니다.


비 정적 Context 메소드 getText() 의 혼합이 static final String 과 함께 사용될 수없는 이유에 대한 설명이있는 좋은 답변이 이미 있습니다.

묻기 좋은 질문은 : 왜 이것을하고 싶습니까? strings 리소스에서 String 을로드하고 해당 값을 public static 필드에 채우려고합니다. 다른 클래스의 일부가이 클래스에 액세스 할 수 있다고 가정합니다. 그렇다면이를 수행 할 필요가 없습니다. 대신 다른 클래스에 Context 를 전달하고 그 내부에서 context.getText(R.string.TTT) 를 호출하십시오.

public class NonActivity {

    public static void doStuff(Context context) {
        String TTT = context.getText(R.string.TTT);
        ...
    }
}

그리고 이것을 당신의 Activity 에서 불러내는 것 :

NonActivity.doStuff(this);

이렇게하면 public static 필드를 사용할 필요없이 String 리소스에 액세스 할 수 있습니다.


네, staticmethod 데코레이터 사용하기

class MyClass(object):
    @staticmethod
    def the_static_method(x):
        print x

MyClass.the_static_method(2) # outputs 2

일부 코드는 정적 메서드를 정의하는 이전 메서드를 사용하며 데코레이터가 아닌 함수로 static 메서드를 사용합니다. 고대 버전의 Python (2.2 및 2.3)을 지원해야하는 경우에만 사용해야합니다.

class MyClass(object):
    def the_static_method(x):
        print x
    the_static_method = staticmethod(the_static_method)

MyClass.the_static_method(2) # outputs 2

이것은 첫 번째 예제 ( @staticmethod 사용)와 완전히 동일하며 좋은 데코레이터 구문을 사용하지 않습니다.

마지막으로, staticmethod 조금 사용하십시오! 파이썬에서 정적 메소드가 필요한 상황은 거의 없으며, 별도의 "최상위 레벨"함수가 더 명확 해졌을 때 여러 번 사용되는 것을 보았습니다.

staticmethod .

정적 메서드는 암시 적 첫 번째 인수를받지 않습니다. 정적 메서드를 선언하려면이 관용구를 사용하십시오.

class C:
    @staticmethod
    def f(arg1, arg2, ...): ...

@staticmethod 양식은 함수 decorator 입니다. 자세한 내용은 함수 정의에서 함수 정의에 대한 설명을 참조하십시오.

클래스 ( Cf() ) 또는 인스턴스 (예 : C().f() )에서 호출 할 수 있습니다. 인스턴스는 해당 클래스를 제외하고 무시됩니다.

파이썬의 정적 메서드는 Java 또는 C ++에서 발견되는 정적 메서드와 비슷합니다. 보다 진보 된 개념은 classmethod() 참조하십시오.

정적 메소드에 대한 자세한 정보는 표준 유형 계층 구조의 표준 유형 계층 구조에 대한 문서를 참조하십시오.

버전 2.2에서 새로 추가되었습니다.

버전 2.4에서 변경 : 함수 장식 자 구문이 추가되었습니다.





java compiler-errors static-methods