名前でクラスを取得する


81

アプリケーションにTestActivityというActivityクラスがある場合、次の例のように、そのクラスを名前で取得する方法はありますか?

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

回答:


162

代わりにforNameを使用してください

このようなもの..

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

30
完全なパッケージ名も指定する必要があります。例:Class.forNameへの引数としてのcom.bla.TestActivity
Richie

1
あなたも受け取るために何かをすることができますClass<? extends SomeClass>か?
ゴブリンズ2017年

@Gobliinsいいえ-コンパイラは、取得するクラスの種類を保証できないため、クラス<?>を提供します。取得するクラスの種類がわかっている場合は、それをキャストする必要があります(それでも、キャストは安全ではないため、チェックされていないキャスト警告が表示されます)。
Dylanthepiguy 2017

1
@Gobliins特定のタイプのサブクラスを取得する方法についての私の答えを確認しください。
raphinesse

7

を使用Class::forNameして、タイプが不明なクラスオブジェクトを取得できます。型付きクラスを取得したい場合Class::asSubclassは、Class::forName:によって返されるクラスで使用できます。

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

もちろん、さまざまな種類の例外も処理する必要があります。反射を扱うときはいつものように。


6

Class.forNameのは、その上の例外を持っているようです。これは、この問題に対処するために上記を拡張するためのものです。

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

SOでこのように答える通常の方法は、答えを編集することです。Javaには例外がたくさんあるので(そしてあなたのコードはそれを単に無視します)、コメントはそれに対処するのに十分でしょう。
tsn 2015年

7
@ crazyhatfish-パトリックには、自分の答え投稿する以外に役立つことする特権がなかったようです。
2015

4
@amessおっと、あなたの権利、私はコメントが担当者を必要とすることを忘れます。私を訂正してくれてありがとう。
tsn 2015

2

同様の要件もありました。画面とアクティビティのマッピングを含むバックエンドからのjsonがありました。jsonはiOS / Androidの両方に共通しているため、jsonにのような用語を追加できActivityなかったため、これを実行しました

  1. すべてのためのJSONではActivityまたはViewcontrollers、版IEの単純な名前を使用HomeActivityしてHomeViewController、我々はJSONで「ホーム」を使用します

  2. アプリでは、jsonを解析し、アクティビティを動的に取得するために以下のユーティリティメソッドを作成しました

クラスの名前を取得するには(つまり、Homeを通過すると、戻りますcom.package.HomeActivity

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

文字列からクラスを取得します

        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()
        }

このようにして、同じメソッドで複数のクラスを簡単に管理できます。これは、すべてのセルが異なるアクティビティに移動するリサイクラービューで使用します。


あなたの答えはKotlinにあることに注意してください;)おそらくそれをJavaにするために少し変更しますか?
LMD

@LMDおそらく、答えを探しているほとんどのAndroid開発者は、Javaではなくkotlinバージョンを必要としています;)
RuslanBerozov19年

@RuslanBerozov opは質問に[java]のタグを付けているので、少なくともJavaバージョンを期待します(もちろん、追加のKotlinでも問題ありません)。
LMD

@LMD申し訳ありませんが、opは2012年に質問を投稿しました。彼が当時Kotlinについて知っていたとは想像しがたいです。重要なのは、質問も[android]とマークされていることです。最近では、Kotlinバージョンが望ましいと思います。
RuslanBerozov19年

-2

それはあなたの質問に最も関連性のある答えではないかもしれませんが、クラス名リテラルを文字列としてハードコーディングすることは一般的に悪いことです。使用したほうがいいかもしれません

Class<?> act = TestActivity.class;

構文。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.