Statik olmayan yönteme statik bir referans yapılamaz


102

Java'da çok dilli bir uygulama oluşturma. R.stringKaynak XML dosyasından String değeri eklerken hata alınıyor :

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

Bu hata mesajıdır:

Hata: Bağlam türünden statik olmayan getText (int) yöntemine statik bir başvuru yapılamaz

Bu nasıl oluşur ve bunu nasıl çözebilirim?


1
Bir 'çok dilli uygulama' için neden statik olmasına ihtiyacınız var? Gerçekten anlamıyorum.
xil3

3
Dize kaynaklarını asla statik veri üyelerinde saklamayın. getString()İhtiyaç duyduğunuzda her zaman isteyin . Bu şekilde uygulamanız, kullanıcıların seçtikleri dili değiştirmesine uygun şekilde ayarlanır.
CommonsWare

Yanıtlar:


143

Yana getText()olmayan statik statik yönteminden diyemezsin.

Nedenini anlamak için ikisi arasındaki farkı anlamalısınız.

Örnek (statik olmayan) yöntemler, belirli bir türdeki (sınıf) nesneler üzerinde çalışır. Bunlar şu şekilde yenilerle oluşturulur:

SomeClass myObject = new SomeClass();

Bir örnek yöntemini çağırmak için, onu örnekte ( myObject) çağırırsınız :

myObject.getText(...)

Bununla birlikte, statik bir yöntem / alan yalnızca doğrudan tipte çağrılabilir , şöyle söyleyin: Önceki ifade doğru değil. Bir nesne referansıyla statik alanlara da atıfta bulunulabilir, myObject.staticMethod() ancak bu tavsiye edilmez çünkü bunların sınıf değişkenleri olduklarını netleştirmez.

... = SomeClass.final

Ve ikisi farklı veri alanlarında (örnek verileri ve sınıf verileri) çalıştıkları için birlikte çalışamazlar.

Deneyip açıklamama izin ver. Bu sınıfı düşünün (psuedocode):

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

Şimdi şu kullanım durumum var:

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

 Test item2 = new Test();

 Test.TTT = "1";

Değerler neler?

İyi

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

Başka bir deyişle, TTTtipin tüm örnekleri tarafından paylaşılan bir datumdur. Bu yüzden söylemenin bir anlamı yok

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

Asıl sorun, neden olduğu TTT statik ya da neden gettext () statik değildir?

Kaldır staticve bu hatayı geçmelidir - ancak türünüzün ne yaptığını anlamadan, bir sonraki hataya kadar sadece yapışkan bir alçıdır. getText()Statik olmamasını gerektiren gereksinimler nelerdir ?


statik çünkü projemdeki birkaç dosyadan çağırıyorum. "Statik" i kaldırdığımda hata kodu gitmiş, ancak şimdi bu değişkeni kullanan diğer dosyalarda birçok hata var.
Chen M

Ama benim açımdan bu. İkisinin ne zaman kullanılabileceğini anlamanız gerekir.
Preet Sangha

Ana aktivite sınıfıma "Sabit bildirimler_değerleri = yeni Sabitler (); satırını eklediğimde, Tamam'ı derler, ancak öykünücüde bu etkinlik çalıştığında çöküyor
Chen M

12

Statik olmayan Contextyöntemin karışımının neden sizin cihazınızla kullanılamayacağına dair açıklamalar içeren bazı iyi cevaplar zaten getText()var.static final String .

Sorulacak iyi bir soru şudur: Bunu neden yapmak istiyorsun? Bir yüklemeye çalışıyorsunuz Stringsizin gelen stringskaynak ve içine değerini doldurmak public staticalanında. Bunun diğer sınıflarınızdan bazılarının erişebilmesi için olduğunu varsayıyorum. Eğer öyleyse, buna gerek yoktur. Bunun yerine Contextdiğer sınıflarınıza a verin ve context.getText(R.string.TTT)onların içinden arayın .

public class NonActivity {

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

Ve buna sizden seslenmek için Activity:

NonActivity.doStuff(this);

Bu, Stringbir public staticalanı kullanmanıza gerek kalmadan kaynağınıza erişmenizi sağlayacaktır .


1
çok teşekkür ederim, tüm dosyaları senin tavsiyene göre değiştirdim.
Chen M

Bunu yapmaya çalışıyordum, ama bir dizge dizisi için ve ile String a[] = context.getTextArray(R.array.myStringArray); ; yine de bana bir hata veriyor The method getTextArray(int) is undefined for the type Context- getText ile çalışırken neden tanımsız olsun?
hayırlı99

1
@ auspicious99, çünkü a Contextadında bir yönteme sahip değil getTextArray, ancak var getText. Belki de düşünüyoruz Resourceski vargetTextArray
dave.c

Ah teşekkürler! Bağlam yerine Kaynaklar (etkinlikten eylemsizliğe) geçti ve getStringArray çalıştım.
hayırlı99

9

bunu aramada bulan diğerleri için:

Nesne adı yerine sınıf adını kullanarak yanlışlıkla bir işlevi çağırdığımda bunu sıklıkla alıyorum. Bu genellikle onlara çok benzer isimler verdiğim için olur: P

yani:

MyClass myclass = new MyClass();

// then later

MyClass.someFunction();

Bu açıkça statik bir yöntemdir. (bazı şeyler için iyidir) Ama gerçekten yapmak istediğim şey (çoğu durumda)

myclass.someFunction();

Bu çok aptalca bir hata, ama her iki ayda bir, "Sınıfım" tanımlarındaki değişkenlerle uğraşarak yaklaşık 30 dakika harcıyorum, gerçekten neyi yanlış yaptığımı bulmak için, bu sadece bir yazım hatası.

Komik not: yığın taşması, burada hatayı gerçekten belirgin hale getirmek için sözdizimini vurgular.


IDE'niz de bunu vurgulamıyor mu? Sanırım bunu yapacak şekilde yapılandırabilirsiniz :)
Matthias Meid

2

Değişkeninizi statik olmayan yapabilirsiniz

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

veya "getText" yöntemini statik yapın (mümkünse)


2

getText, Aktivitenizin bir üyesidir, bu nedenle "bu" mevcut olduğunda çağrılmalıdır. Statik değişkeniniz, Aktiviteniz oluşturulmadan önce sınıfınız yüklendiğinde başlatılır.

Değişkenin bir Kaynak dizesinden başlatılmasını istediğiniz için, statik olamaz. Statik olmasını istiyorsanız, onu String değeri ile başlatabilirsiniz.


2

Statik olmayan yöntemden statik değişkene başvuru yapamazsınız. Bunu anlamak için statik ve statik olmayan arasındaki farkı anlamanız gerekir.

Statik değişkenler sınıf değişkenleridir, yalnızca ilkinde oluşturulan tek bir örneği ile sınıfa aittirler. Statik olmayan değişkenler, sınıfın bir nesnesini her oluşturduğunuzda başlatılır.

Şimdi sorunuza gelince, new () operatörünü kullandığınızda, her nesne için statik olmayan dosyalanmış her bir nesnenin kopyasını oluşturacağız, ancak bu statik alanlar için geçerli değildir. Bu nedenle, statik olmayan bir yöntemden statik bir değişkene başvuruyorsanız derleme zamanı hatası verir.


0

Bu soru yeni değil ve mevcut cevaplar iyi bir teorik arka plan sağlıyor. Daha pragmatik bir cevap eklemek istiyorum.

getText, Context abstract sınıfının bir yöntemidir ve onu çağırmak için, alt sınıfının bir örneğine ihtiyaç duyar (Etkinlik, Hizmet, Uygulama veya diğerleri). Sorun, public static son değişkenlerinin herhangi bir Context örneği yaratılmadan önce başlatılmasıdır.

Bunu çözmenin birkaç yolu var:

  1. Statik değiştiriciyi kaldırarak ve onu sınıf gövdesine yerleştirerek değişkeni Aktivitenin veya Bağlamın diğer alt sınıfının bir üye değişkeni (alanı) yapın;
  2. Statik tutun ve başlatmayı daha sonraki bir noktaya erteleyin (örn. OnCreate yönteminde);
  3. Gerçek kullanım yerine yerel bir değişken yapın.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.