3

私はそれが不可能だと思いますが、私は疑問に思っていました:

特定のインターフェイスにメソッドごとに準拠するクラスをキャストできますか(ただし、「実装インターフェイス」は使用しません)、そのインターフェイスにキャストできますか?

回避策はありますか?特定のクラスにラッパークラスを使用したいのですが、そのコンストラクターにアクセスできず、そのクラスを予期する受信コードを変更する方法がありません。

-編集-申し訳ありませんが、インターフェイスについて明確ではありませんでした。実際には、2つの考え方が1つの質問に統合されたものです。クラスを別のクラスにキャストすることについて質問する必要がありました。

4

4 に答える 4

4

簡単な答えはノーです。システムはどうやって知ることができるでしょうか?それはせいぜい偶然でしょう。

回避策の観点から、リフレクションはここでのあなたの友達です。 Oracleチュートリアル

コード例:

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Member;
import static java.lang.System.out;

enum ClassMember { CONSTRUCTOR, FIELD, METHOD, CLASS, ALL }

public class ClassSpy {
    public static void main(String... args) {
    try {
        Class<?> c = Class.forName(args[0]);
        out.format("Class:%n  %s%n%n", c.getCanonicalName());

        Package p = c.getPackage();
        out.format("Package:%n  %s%n%n",
               (p != null ? p.getName() : "-- No Package --"));

        for (int i = 1; i < args.length; i++) {
        switch (ClassMember.valueOf(args[i])) {
        case CONSTRUCTOR:
            printMembers(c.getConstructors(), "Constructor");
            break;
        case FIELD:
            printMembers(c.getFields(), "Fields");
            break;
        case METHOD:
            printMembers(c.getMethods(), "Methods");
            break;
        case CLASS:
            printClasses(c);
            break;
        case ALL:
            printMembers(c.getConstructors(), "Constuctors");
            printMembers(c.getFields(), "Fields");
            printMembers(c.getMethods(), "Methods");
            printClasses(c);
            break;
        default:
            assert false;
        }
        }

        // production code should handle these exceptions more gracefully
    } catch (ClassNotFoundException x) {
        x.printStackTrace();
    }
    }
于 2013-01-10T21:33:10.093 に答える
1

いいえ、他のポスターがすでに回答しているので、できません。

(醜い)回避策の場合:を使用java.lang.Reflectionして、プライベートコンストラクターを含む任意のコンストラクターにアクセスできます。

リフレクションによってプライベートno-argコンストラクターを介してオブジェクトをインスタンス化する例:

java.lang.reflect.Constructor[] c = clazz.getDeclaredConstructors();
c[0].setAccessible(true);
Object instance = c[0].newInstance(new Object[] {});

ただし、私の人生で一度、リフレクションを介してプライベートフィールドにアクセスできないように(SecurityManagerを介して)構成されたVMを見たことがあることに注意してください。

于 2013-01-10T21:35:19.380 に答える
0

オブジェクトの継承チェーンにないクラスにオブジェクト参照をキャストしたり、オブジェクトが実装していないインターフェイスにキャストしたりすることはできません。これを防ぐために実行されるランタイムチェックがあります。

(そして、参照の配列をキャストすることになると、さらに制限が厳しくなります。)

于 2013-01-10T21:36:04.443 に答える
0

いいえ。ただし、アダプタ設計パターンを使用してこの問題を解決できます。インターフェイスを実装し、問題のクラスのインスタンスをコンストラクターパラメーターとして受け取るクラスを作成します。次に、すべてのメソッドをこのインスタンスに委任します。

于 2013-01-10T21:41:29.947 に答える