it-swarm.com.de

Kann keine statische Referenz auf die nicht statische Methode erstellen

Erstellen einer mehrsprachigen Anwendung in Java. Beim Einfügen eines String-Werts aus der R.string-Ressource-XML-Datei wird ein Fehler angezeigt:

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

Dies ist die Fehlermeldung:

Fehler: Es kann keine statische Referenz auf die nicht statische Methode getText (int) vom Typ .__ erstellt werden. Kontext

Wie wird das verursacht und wie kann ich es lösen?

92
Chen M

Da getText() nicht statisch ist, können Sie es nicht mit einer statischen Methode aufrufen.

Um zu verstehen, warum, müssen Sie den Unterschied zwischen den beiden verstehen.

Instanzen (nicht statisch) arbeiten mit Objekten eines bestimmten Typs (der Klasse). Diese werden mit dem Neuen so erstellt:

SomeClass myObject = new SomeClass();

Um eine Instanzmethode aufzurufen, rufen Sie sie in der Instanz (myObject) auf:

myObject.getText(...)

Eine statische Methode/ein statisches Feld kann jedoch direkt mit dem Typ only bezeichnet werden.Die vorherige Anweisung ist nicht korrekt. Man kann auch auf statische Felder mit einer Objektreferenz wiemyObject.staticMethod() verweisen, aber dies wird nicht empfohlen, da nicht deutlich wird, dass es sich um Klassenvariablen handelt. 

... = SomeClass.final

Und die beiden können nicht zusammenarbeiten, da sie mit unterschiedlichen Datenräumen arbeiten (Instanzdaten und Klassendaten).

Lass es mich versuchen und erklären. Betrachten Sie diese Klasse (Psuedocode):

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

Jetzt habe ich den folgenden Anwendungsfall:

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

 Test item2 = new Test();

 Test.TTT = "1";

Was sind die Werte?

Gut

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

Anders ausgedrückt ist TTT ein Datum, das von allen Instanzen des Typs gemeinsam genutzt wird. Also macht es keinen Sinn zu sagen 

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

Die Frage ist also, warum TTT statisch ist oder warum getText () nicht statisch ist. 

Entfernen Sie die Variable static, und es sollte an diesem Fehler vorbeigehen. Wenn Sie jedoch nicht wissen, was Ihr Typ tut, ist es nur ein Pflaster bis zum nächsten Fehler. Was sind die Anforderungen von getText(), die erfordern, dass es nicht statisch ist?

136
Preet Sangha

Es gibt bereits einige gute Antworten mit Erklärungen, warum die Mischung der nicht statischen Context-Methode getText() nicht mit Ihrem static final String verwendet werden kann.

Eine gute Frage ist: Warum willst du das? Sie versuchen, eine String von Ihrer strings-Ressource zu laden und deren Wert in ein public static-Feld zu füllen. Ich gehe davon aus, dass dies so ist, dass einige Ihrer anderen Klassen darauf zugreifen können? Wenn ja, ist dies nicht erforderlich. Übergeben Sie stattdessen eine Context in Ihre anderen Klassen und rufen Sie context.getText(R.string.TTT) von dort aus auf.

public class NonActivity {

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

Und um dies von Ihrer Activity zu nennen:

NonActivity.doStuff(this);

Auf diese Weise können Sie auf Ihre String-Ressource zugreifen, ohne ein public static-Feld verwenden zu müssen.

11
dave.c

für andere, die dies in der Suche finden:

Ich bekomme diese oft, wenn ich versehentlich eine Funktion mit dem Klassennamen anstelle des Objektnamens aufrufe. Dies geschieht normalerweise, weil ich ihnen zu ähnliche Namen gebe: P

dh: 

MyClass myclass = new MyClass();

// then later

MyClass.someFunction();

Dies ist offensichtlich eine statische Methode. (gut für etwas) Aber was ich wirklich tun wollte (war in den meisten Fällen)

myclass.someFunction();

Es ist ein dummer Fehler, aber alle paar Monate vergeude ich in den Definitionen von "MyClass" etwa 30 Minuten, um mich mit vars zu beschäftigen, um herauszufinden, was ich falsch mache, wenn es wirklich etwas ist. 

Lustiger Hinweis: Stack-Überlauf hebt die Syntax hervor, um den Fehler hier deutlich zu machen. 

8
SpiRail

Sie können Ihre Variable entweder nicht statisch machen

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

oder die "getText" -Methode statisch machen (wenn überhaupt möglich)

2
Kellindil

getText ist ein Mitglied Ihrer Aktivität, daher muss es aufgerufen werden, wenn "this" vorhanden ist. Ihre statische Variable wird initialisiert, wenn Ihre Klasse geladen wird, bevor Ihre Aktivität erstellt wird.

Da Sie möchten, dass die Variable aus einer Ressourcenzeichenfolge initialisiert wird, kann sie nicht statisch sein. Wenn Sie möchten, dass es statisch ist, können Sie es mit dem String-Wert initialisieren.

2
Robby Pond

Sie können sich nicht auf eine statische Variable aus der nicht statischen Methode beziehen .. Um dies zu verstehen, müssen Sie den Unterschied zwischen statisch und nicht statisch verstehen.

Statische Variablen sind Klassenvariablen. Sie gehören mit ihrer einzigen Instanz zur Klasse .. _. Nicht statische Variablen werden jedes Mal initialisiert, wenn Sie ein Objekt der Klasse erstellen.

Nun zu Ihrer Frage. Wenn Sie den new () - Operator verwenden, erstellen wir für jedes Objekt eine Kopie jedes nicht statischen Felds. Dies gilt jedoch nicht für statische Felder. Aus diesem Grund wird ein Fehler beim Kompilieren angezeigt, wenn Sie eine statische Variable aus einer nicht statischen Methode referenzieren.

1
Krishna

Diese Frage ist nicht neu und die vorhandenen Antworten geben einen guten theoretischen Hintergrund. Ich möchte nur eine pragmatischere Antwort hinzufügen. 

getText ist eine Methode der abstrakten Context-Klasse. Um sie aufzurufen, benötigt man eine Instanz ihrer Unterklasse (Activity, Service, Application oder andere). Das Problem ist, dass die öffentlichen statischen final-Variablen vor dem Erstellen einer Instanz von Context initialisiert werden.

Es gibt mehrere Möglichkeiten, dies zu lösen: 

  1. Machen Sie die Variable zu einer Mitgliedsvariablen (Feld) der Aktivität oder einer anderen Unterklasse von Context, indem Sie den statischen Modifikator entfernen und ihn innerhalb des Klassenhauptteils platzieren.
  2. Behalten Sie es statisch und verzögern Sie die Initialisierung zu einem späteren Zeitpunkt (z. B. in der onCreate-Methode).
  3. Machen Sie eine lokale Variable anstelle der tatsächlichen Verwendung.
0
dev.bmax