İsmine göre sınıf almak


81

Uygulamamda TestActivity adlı bir Activity sınıfım varsa, bu örnekte olduğu gibi sınıfını adına göre almanın bir yolu var mı:

Class<?> c = getClassByName("TestActivity");

Yanıtlar:


162

kullanmak forName yerine ..

bunun gibi bir şey ...

 try {
    Class<?> act = Class.forName("com.bla.TestActivity");
 } catch (ClassNotFoundException e) {
        e.printStackTrace();
}

30
Tam paket adını da vermelisiniz. örn: com.bla.TestActivity, Class.forName'e bağımsız değişken olarak
Richie

1
Sen de almak için bir şeyler yapabilir misin Class<? extends SomeClass>?
Gobliins

@Gobliins Hayır - derleyici ne tür bir sınıf alacağınızı garanti edemez, bu nedenle size bir Sınıf <?> Verir. Ne tür bir sınıf alacağınızı biliyorsanız, onu atmanız gerekir (yine de, kontrolsüz atma uyarıları alırsınız çünkü oyuncu seçimi güvenli değildir).
Dylanthepiguy

1
@Gobliins göz atın cevabım belli türde bir alt sınıfı almak için nasıl.
raphinesse

7

Class::forNameBilinmeyen türde bir sınıf nesnesi almak için kullanabilirsiniz . Daktilo edilmiş bir sınıf almak istiyorsanız, şu şekilde Class::asSubclassdöndürülen sınıfta kullanabilirsiniz Class::forName:

Class<? extends Activity> activityClass = Class.forName("com.example.TestActivity")
                                               .asSubclass(Activity.class);

Elbette bir dizi farklı istisna türünü de ele almanız gerekecek. Yansıma ile uğraşırken her zamanki gibi.


6

Class.forName Üzerinde istisnalar var gibi gözüküyor. Bu, bu sorunu çözmek için yukarıdakileri genişletmek içindir.

try { t = Class.forName("com.package.classname"); } catch (Exception ignored){}

SO'da bu şekilde cevap vermenin olağan yolu, cevaplarını düzenlemek olacaktır . Java'da istisnalar çok olduğu için (ve kodunuz bunu görmezden geliyor), bu konuyu ele almak için bir yorum yeterli olacaktır.
tsn

7
@crazyhatfish - Görünüşe göre Patrick kendi cevabını göndermek dışında yararlı bir şey yapma ayrıcalığına sahip olmamış olabilir .
amess

4
@amess Eyvah, haklısın, yorumların tekrar edilmesi gerektiğini unuttum. Beni düzelttiğin için teşekkürler.
tsn

2

Benim de benzer bir gereksinimim vardı, arka uçtan gelen ekran ve aktivite haritalamasını içeren bir json'um vardı. Hem iOS hem de Android için json ortak olduğundan, json'a benzer terimler ekleyemedik Activity, bu yüzden yaptığımız şey buydu

  1. Herkes için json'da Activityveya Viewcontrollersbasit isimler kullanın, ör. İçin HomeActivityve HomeViewControllerjson'da "Home" kullanacağız.

  2. Uygulamada, json'u ayrıştırıyoruz ve etkinliği dinamik olarak elde etmek için aşağıdaki yardımcı program yöntemlerini yazdım

Sınıfın adını almak için (yani Evden geçersek geri döneceğiz com.package.HomeActivity)

    fun getClassInfoFor(name: String, context: Context):String{
        var str = "${context.getPackageName()}.${name}Activity"
        return str
    }

Şimdi dizeden sınıf almak için

        try {
            val className = Utilties.getClassInfoFor(activityNameFromJSON, context)
            val fetchedClass = Class.forName(className)
            val showDetailsIntent = Intent(context, fetchedClass)
            context.startActivity(showDetailsIntent)
        } catch (e: ClassNotFoundException) {
            e.printStackTrace()
        }

Bu şekilde birden fazla sınıfı aynı yöntemle kolayca yönetebilirim. Bunu, her hücremin farklı bir aktiviteye gittiği bir geri dönüşüm görünümünde kullanıyorum.


Cevabınızın Kotlin'de olduğunu lütfen unutmayın;) Muhtemelen Java yapmak için biraz değiştirir misiniz?
LMD

@LMD muhtemelen cevap arayan android geliştiricilerin çoğu java'ya değil kotlin sürümüne ihtiyaç duyuyor;)
Ruslan Berozov

@RuslanBerozov Operasyon soruyu [java] olarak etiketledi, bu yüzden en azından bir Java sürümü bekliyorum (ek Kotlin de iyi tabi ki).
LMD

@LMD özür dilerim ama op 2012'de bir soru yayınladı. O sırada Kotlin'i bildiğini hayal etmek gerçekten zor. Mesele şu ki, bu soru da [android] olarak işaretlenmiş ve bugünlerde Kotlin versiyonunu tercihen bekliyorum.
Ruslan Berozov

-2

Sorunuz için en alakalı cevap olmayabilir, ancak sınıf adı değişmezlerini dizge olarak kodlamak genellikle kötüdür. Kullanması daha iyi olabilir

Class<?> act = TestActivity.class;

sözdizimi.

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.