자바로 다국어 애플리케이션 구축. 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()
비 정적이어야 하는 요구 사항은 무엇입니까 ?
답변
비 정적 Context
방법 의 혼합을 getText()
사용할 수없는 이유에 대한 설명과 함께 이미 좋은 답변 이 있습니다.static final String
.
물어볼 좋은 질문은 다음과 같습니다.이 작업을 수행하려는 이유는 무엇입니까? 리소스 String
에서 를로드하고 strings
해당 값을 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);
이렇게하면 필드 String
를 사용하지 않고도 리소스 에 액세스 할 수 있습니다 public static
.
답변
검색에서 이것을 찾은 다른 사람들을 위해 :
나는 실수로 객체 이름이 아닌 클래스 이름을 사용하여 함수를 호출 할 때 종종 이것을 얻습니다. 이것은 일반적으로 너무 비슷한 이름을 제공하기 때문에 발생합니다 .P
즉 :
MyClass myclass = new MyClass();
// then later
MyClass.someFunction();
이것은 분명히 정적 방법입니다. (뭔가에 좋다)하지만 내가 정말로하고 싶었던 것은 (대부분의 경우)
myclass.someFunction();
정말 어리석은 실수이지만, 몇 달에 한 번씩 “MyClass”정의에서 vars를 엉망으로 만드는 데 약 30 분을 허비하여 실제로 오타 일 때 잘못하고있는 일을 해결합니다.
재미있는 참고 사항 : 스택 오버플로는 여기서 실수를 분명하게 만드는 구문을 강조합니다.
답변
변수를 비 정적으로 만들 수 있습니다.
public final String TTT = (String) getText(R.string.TTT);
또는 “getText”메서드를 정적으로 만듭니다 (가능한 경우).
답변
getText는 활동의 구성원이므로 “this”가있을 때 호출해야합니다. 활동이 생성되기 전에 클래스가로드되면 정적 변수가 초기화됩니다.
리소스 문자열에서 변수를 초기화하기를 원하므로 정적 일 수 없습니다. 정적으로 만들려면 String 값으로 초기화 할 수 있습니다.
답변
비 정적 메서드에서는 정적 변수를 참조 할 수 없습니다. 이를 이해하려면 정적과 비 정적의 차이점을 이해해야합니다.
정적 변수는 클래스 변수이며 처음에만 생성 된 인스턴스가 하나 뿐인 클래스에 속합니다. 비 정적 변수는 클래스의 객체를 만들 때마다 초기화됩니다.
이제 질문에 도달하면 new () 연산자를 사용할 때 모든 객체에 대해 모든 비 정적 파일의 복사본을 만들지 만 정적 필드의 경우는 그렇지 않습니다. 그렇기 때문에 비 정적 메서드에서 정적 변수를 참조하는 경우 컴파일 시간 오류가 발생합니다.
답변
이 질문은 새로운 것이 아니며 기존 답변은 좋은 이론적 배경을 제공합니다. 좀 더 실용적인 답변을 추가하고 싶습니다.
getText는 Context 추상 클래스의 메서드이며이를 호출하려면 하위 클래스 (Activity, Service, Application 또는 기타)의 인스턴스가 필요합니다. 문제는 Context 인스턴스가 생성되기 전에 공개 정적 최종 변수가 초기화된다는 것입니다.
이 문제를 해결하는 방법에는 여러 가지가 있습니다.
- 정적 수정자를 제거하고 클래스 본문 내에 배치하여 변수를 Activity 또는 Context의 다른 하위 클래스의 멤버 변수 (필드)로 만듭니다.
- 정적으로 유지하고 초기화를 나중에 (예 : onCreate 메서드에서) 지연시킵니다.
- 실제 사용 대신 지역 변수로 만드십시오.