85

という名前の基本クラスがあるとしましょうEntity。そのクラスには、クラス名を取得するための静的メソッドがあります。

class Entity {
    public static String getClass() {
        return Entity.class.getClass();
    }
}

今、私はそれを拡張する別のクラスを持っています。

class User extends Entity {
}

Userのクラス名を取得したい:

System.out.println(User.getClass());

私の目標は、コンソールに「com.packagename.User」の出力を表示することですが、Entityクラスは静的メソッドから直接参照されているため、代わりに「com.packagename.Entity」になります。

これが静的メソッドでない場合は、クラスthis内のキーワード(つまり、:)を使用することで簡単に解決できます。ただし、このメソッドを静的に保つ必要があります。これにアプローチする方法について何か提案はありますか?Entityreturn this.class.getClass()

4

12 に答える 12

102

メソッドを静的にしないでください。問題は、呼び出すときgetClass()にスーパークラスのメソッドを呼び出していることです。静的メソッドは継承されません。さらに、あなたは基本的に名前をシャドウイングObject.getClass()しているので、混乱を招きます。

スーパークラス内のクラス名をログに記録する必要がある場合は、

return this.getClass().getName();

これにより、インスタンスがある場合は「Entity」、Entityインスタンスがある場合は「User」Userなどが返されます。

于 2010-08-05T18:36:54.423 に答える
42

ありえない。静的メソッドは、実行時のポリモーフィックではありません。これらのケースを区別することは絶対に不可能です。

System.out.println(Entity.getClass());
System.out.println(User.getClass());

それらは同じバイトコードにコンパイルされます(メソッドがで定義されていると仮定しますEntity)。

さらに、多型であることが理にかなっている方法で、このメソッドをどのように呼び出しますか?

于 2010-08-05T18:37:47.007 に答える
8

これは私のために働く

this.getClass().asSubclass(this.getClass())

しかし、それがどのように機能するかはわかりません。

于 2017-08-01T08:54:53.173 に答える
6

あなたの質問はあいまいですが、私が知る限り、静的メソッドから現在のクラスを知りたいと思います。クラスが相互に継承するという事実は関係ありませんが、説明のために、この方法でも実装しました。

クラス親{
    public static void printClass(){
      System.out.println(Thread.currentThread()。getStackTrace()[2] .getClassName());
    }
}

パブリッククラスTestはParent{を拡張します
    public static void main(String [] args){
      printClass();
    }
}
于 2010-08-05T18:44:43.593 に答える
3

スーパークラスは、サブクラスの存在さえ知らないはずです。ましてや、サブクラスの完全修飾名に基づいて操作を実行する必要はありません。正確なクラスに基づいた操作が必要であり、継承によって必要な機能を実行できない場合は、次のように実行する必要があります。

public class MyClassUtil
{
    public static String doWorkBasedOnClass(Class<?> clazz)
    {
        if(clazz == MyNormalClass.class)
        {
            // Stuff with MyNormalClass
            // Will not work for subclasses of MyNormalClass
        }

        if(isSubclassOf(clazz, MyNormalSuperclass.class))
        {
            // Stuff with MyNormalSuperclass or any subclasses
        }

        // Similar code for interface implementations
    }

    private static boolean isSubclassOf(Class<?> subclass, Class<?> superclass)
    {
        if(subclass == superclass || superclass == Object.class) return true;

        while(subclass != superclass && subclass != Object.class)
        {
            subclass = subclass.getSuperclass();
        }
        return false;
    }
}

(テストされていないコード)

このクラスは、それ自体のサブクラスについても認識していませんが、Classクラスを使用して操作を実行します。ほとんどの場合、それはまだ実装と緊密にリンクされています(一般的に悪いこと、または悪くない場合は特に良くありません)が、このような構造は、すべてのサブクラスが何であるかを理解するスーパークラスよりも優れていると思います。

于 2010-08-05T18:56:34.070 に答える
2

なぜ独自のgetClass()メソッドを実装したいのですか?あなたはただ使うことができます

System.out.println(User.class);

編集(少し詳しく説明します):メソッドを静的にする必要があります。その場合、サブクラスであれスーパークラスであれ、クラス名が必要なクラスのメソッドを呼び出す必要があります。次に、を呼び出す代わりに、またはを呼び出すMyClass.getClass()ことができます。MyClass.classMyClass.class.getName()

また、インスタンスメソッドstaticと同じシグネチャを持つメソッドを作成していますが、これはコンパイルされません。Object.getClass()

于 2010-08-05T18:29:47.973 に答える
2
  1. スーパークラスにメンバーString変数を作成します。
  2. this.getClass()。getName()を、メンバーのString変数に値を格納するコンストラクターに追加します。
  3. 名前を返すゲッターを作成します。

拡張クラスがインスタンス化されるたびに、その名前が文字列に格納され、ゲッターでアクセスできるようになります。

于 2013-09-11T21:37:03.663 に答える
0

静的メソッドは、特定のオブジェクトではなく、クラスに関連付けられています。

複数のサブクラスがある場合、これがどのように機能するかを検討してください。たとえば、Administratorもエンティティです。Entityクラスにのみ関連付けられている静的Entityメソッドは、どのサブクラスが必要かをどのように認識しますか?

あなたは出来る:

  • 既存のgetClass()メソッドを使用します。
  • 静的getClass()メソッドに引数を渡し、そのオブジェクトのインスタンスメソッドを呼び出します。
  • メソッドを非静的にし、名前を変更します。
于 2010-08-05T18:38:00.767 に答える
0

私があなたの質問を正しく理解している場合、あなたが望むことを達成できる唯一の方法は、各サブクラスに静的メソッドを再実装することだと思います。たとえば、次のようになります。

class Entity {
    public static String getMyClass() {
        return Entity.class.getName();
    }
}

class Derived extends Entity {
    public static String getMyClass() {
        return Derived.class.getName();
    }
}

これにより、必要に応じてpackage.Entityとpackage.Derivedが出力されます。散らかっていますがねえ、それらがあなたの制約であるなら...

于 2010-08-05T18:40:33.520 に答える
0

私が正しく理解している場合は、静的メソッドの基本クラスでサブクラスを使用する必要があります。これは、クラスパラメーターをメソッドに渡すことで実行できると思います。

class Entity {
    public static void useClass(Class c) {
        System.out.println(c);
        // to do code here
    }
}

class User extends Entity {
}

class main{
    public static void main(String[] args){
        Entity.useClass(Entity.class);
    }
}
于 2014-12-18T06:02:33.283 に答える
0

私のコンテキスト:XMLオブジェクトのサブクラスを持つスーパークラスエンティティ。私の解決策:スーパークラスにクラス変数を作成する

Class<?> claz;

次に、サブクラスで、コンストラクターでスーパークラスの変数を設定します

public class SubClass {
   public SubClass() {
     claz = this.getClass();
   }
}
于 2016-07-26T10:19:54.147 に答える
-4

それは非常に簡単です

User.getClass()。getSuperclass()

于 2012-10-10T00:11:25.370 に答える