4

私は持っています

public class A {
    static X s_x = new X(A.class);
}

public class B {
    static X s_x = new X(B.class);
}

特別な関係や共通性のない多くのクラスについても同様です。私が本当にやりたいのは、s_xをスーパークラスで初期化することですが、子孫クラス固有のコードを使用します。静的コードはオーバーライドできないため、これは不可能です。ですから、少なくともコピー&ペーストを簡単にしたいのです。Classオブジェクトに評価される魔法の式が必要です。つまり、次のように記述します。

    static X s_x = new X(/* magic expression here */);

ここで、魔法の式は、Xを宣言するクラスに関係なく同じですが、上記の例と同じです。次善のオプションは、同じ効果をもたらす静的メソッドです。

ノート:

  • 可能であればJava6。
  • この質問は(必然的に)ロギングに関するものではありません...
4

8 に答える 8

1

これは、Java 5以降のJVMで機能し、コードに追加のインポートを追加しないワンライナーです。

new Object(){}.getClass().getEnclosingClass()

匿名の内部クラスを作成し、そのClassオブジェクトを取得してから、それを囲むクラスインスタンスを取得します。これはあなたのクラスである必要があります。例えば:

public class HelloClass {
    static final Class<?> THIS_CLASS = new Object(){}.getClass().getEnclosingClass();

    public static void main(String[] args) {
        System.out.println(THIS_CLASS); // prints "class HelloClass"
    }
}

あなたの質問の文脈で:

static X s_x = new X(new Object(){}.getClass().getEnclosingClass());
于 2013-01-17T19:45:31.410 に答える
1

私も一度この奇妙な要件があり、検索しようとしましたが何も見つかりませんでした。そのため、答えは不可能かもしれないと思います。

しかし、私は自分のアプローチを再考するように言われました、そして私が試みたとき、私はこの奇妙な要件なしで同じ解決策を見つけ出しました。ですから、あなたのアプローチを考え直してください。私のように解決できると思います。また、あなたが解決しようとしている問題/シナリオを投稿することができれば、私が助けることができるかもしれません。

于 2013-01-17T12:39:17.733 に答える
1

java.lang.invoke.MethodHandlesJava 7では、このクラスを使用できます。

Class c = MethodHandle.lookup().lookupClass()

パラメータ化されたバージョンの代わりにraw型を使用することについて警告が表示される可能性がありClass<X>ますが、クラス名を自分でハードコーディングすることに戻らなければ、それを回避する方法がわかりません。

于 2013-01-17T12:42:52.740 に答える
1

HotSpot/OpenJDKでは次を使用できます

 Class c = Reflection.getCallerClass(1)

注:これは内部APIであり、すべてのJVMで機能するとは限りません。

于 2013-01-17T12:56:19.940 に答える
0

ロギングオブジェクトを作成する場合は、lombokを使用してロギングオブジェクトを挿入できます。ページからの例:

@Log
public class LogExample {

  public static void main(String... args) {
    log.error("Something's wrong here");
  }
}
于 2013-01-17T13:22:43.710 に答える
0

ここでの回答のいくつかは解決策のアイデアを持っていますが、私が必要とするコードスニペットではありません。これが、JVMでの作業です。

static X s_x = new X(getClassStatic());

public static Class<?> getClassStatic() {
    try {
        // we're using the third highest stack element, since the
        // first highest is the getStackTrace() method, followed by this method itself. We
        // want the calling code's class.
        String name = Thread.currentThread().getStackTrace()[2].getClassName();
        return Class.forName(name);
    } catch (ClassNotFoundException e) {
        // shouldn't be able to get here...
        return null;
    }
}

または、Peter Lawreyの提案に従って、選択したJVMの場合:

static X s_x = new X(getCallerClass(1));
于 2013-01-17T13:31:58.550 に答える
0

唯一の解決策は、現在のスタックトレース(を参照)からクラス名を抽出することだと思います。これにより、を使用してオブジェクトを取得できるThread.getStackTrace()として与えられますが、これは現在のアプローチよりもはるかに醜いです。StringClassClass.forName(String)

于 2013-01-17T12:41:00.660 に答える
0

これを行うことはできますが、アプローチにいくつかのリファクタリングが必要です。

これを試してみてください:

class X
{

   public X(String cName)
   {
     try
     {
       Class.forName(cName);
      }catch(ClassNotFoundException cne)
       {}
   }
}

public class Test
{
    static X x1 = new X(Thread.currentThread().getStackTrace()[1].getClassName());
}
于 2013-01-17T12:56:20.650 に答える