リフレクション(上)

ディレクトリ

反射

リフレクションは、Javaの最も重要な部分の一つであり、高反射コードの再利用の使用を達成することができます。

図1は、分析、修正、およびクラスオブジェクトを操作する機能を実行するJavaプログラムを指します。
2、ClassクラスはJavaリフレクション機構の基盤であり、私たちはクラスについてクラスのクラス情報を介して取得することができます。
図3は、クラス、クラスのオブジェクトは、Javaアプリケーションプログラムは、現在で実行するためのクラスおよびインタフェースを表します。ClassクラスはJavaのリフレクション機構入口です。
図4に示すように、それによってコードの再利用性を向上させる一つの共通の一般的なクラスに複数のクラス、。

ここに画像を挿入説明

反射クラスクラス三つの形式のインスタンスによって得ることができます。

例:

public class TestReflection {
    public static void main(String[] args) throws ClassNotFoundException {
        Ball ball = new Ball();
        //第一种
        Class<?> ballClassA = ball.getClass();
        //第二种
        Class<?> ballClassB = Ball.class;
        //第三种,在不考虑复杂开发时,用第三种
        Class<?> ballClassC = Class.forName("com.tx.test.reflection.Ball");
        
        System.out.println(ballClassC);
        System.out.println(ballClassC.getName());
        System.out.println(ballClassC.getSimpleName());
    }
}
class Ball{}

結果:

class com.tx.test.reflection.Ball
com.tx.test.reflection.Ball
Ball

これは、3つの方法の特徴:

1、クラス.getClass():クラス・オブジェクト・インスタンスを使用するための明確な必要性を得ます。

2、クラスの.class:インポートプロセスは、明示的なクラスの操作が必要です。

3、Class.forNameの():文字列で記述されたクラス名使用して(複合体の開発を検討する際に非常に便利を使用して文字列を、好ましくない)。

反射とプラント設計

植物はもともと結合を解決するために設計された、静的なカップリングプラントの設計はある程度解決が、限りがあるので、新しいキーワードが避けられないカップリングすることができます。

ここに画像を挿入説明

より1サブクラスのインターフェイスよりも、何百、何千、明らかに不可能、あまりにも多くのトラブルを作成した各クラスが、リフレクションを使用することがある場合には、実現に静的な工場設計上の欠陥を使用して動的プラント設計、必要性は、同じインターフェイスを実装することができ、一般的な方法は、インスタンス化操作を実現することができます。

例:

public class TestTrendsFactory {
    public static void main(String[] args) throws Exception {
        IBall ball = Factory.getInstance("com.tx.test.reflection.BasketBallImpl");
        if (ball != null) {	
            ball.play("篮球");
        }
    }
}

interface IBall {
    /**
     * 玩球
     *
     * @param msg 球的种类
     */
    void play(String msg);
}

class BasketBallImpl implements IBall {

    @Override
    public void play(String msg) {
        System.out.println("【球的种类】玩" + msg + "!!!");
    }
}

class Factory {
    private Factory() {
    }

    /**
     * 根据传入的类进行实例化操作
     * @param msg 传入的类
     * @return  返回实例化后的对象
     */
    public static IBall getInstance(String msg) {
        IBall ball;
        try {
            ball = (IBall) Class.forName(msg).getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            return null;
        }
        return ball;
    }
}

結果:

【球的种类】玩篮球!!!

単一の反射例の設計

シングルトンデザインは、JVMプロセスであることの核心は、インスタンスを1つだけ持つことを許可されています。

ここに画像を挿入説明

例:複数のスレッドが遅延インスタンス化方程式を操作します

public class TestSingleton {
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
              Animal animal = Animal.getInstance();
            }).start();
        }
    }
}

class Animal {
    private static Animal animal;

    private Animal() {
        System.out.println("懒汉式单例设计多线程测试!!!");
    }

    public static Animal getInstance() {
        if (animal == null) {
            animal = new Animal();
        }
        return animal;
    }
}

結果:

懒汉式单例设计多线程测试!!!
懒汉式单例设计多线程测试!!!
懒汉式单例设计多线程测试!!!
懒汉式单例设计多线程测试!!!
懒汉式单例设计多线程测试!!!

単一スレッドの複数の遅延ケース設計動作は、単一の実施形態で実現することができない場合。

解決策:追加の方法で同期が、高い同時実行のマルチスレッドの状態で、それは真剣にパフォーマンスに影響を及ぼします。

ここに画像を挿入説明

例:同期メソッドで追加。

public class TestSingleton {
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
              Animal animal = Animal.getInstance();
            }).start();
        }
    }
}

class Animal {
    private static Animal animal;

    private Animal() {
        System.out.println("懒汉式单例设计多线程测试!!!");
    }

    public synchronized static Animal getInstance() {
        if (animal == null) {
            animal = new Animal();
        }
        return animal;
    }
}

結果:

懒汉式单例设计多线程测试!!!

対処方法2:使用の問題解決には内部で同期と反射法。

ヌル値は、同期コードブロックを決定する理由は、最初のスレッドは、最初はヌル値の外にインスタンス化された複数のスレッドは、また、判断した場合に、例えば、動作に入ることを保証することです直接スレッドを返します偽の後、(わずか数スレッドの遅延がある場合にも入ります)となります。

ここに画像を挿入説明

例:

public class TestSingletonInterior {
    public static void main(String[] args) {

    }
}

class Person {
    private static Person person;

    private Person() {
        System.out.println("内部synchronized懒汉式单例设计!!!");
    }

    public static Person getInstance() {
        if (person == null) {
            synchronized (Person.class) {
                if (person == null) {
                    person = new Person();
                }
            }
        }
        return person;
    }
}

結果:

内部synchronized懒汉式单例设计!!!

ダイナミックプロキシモード

クラス構造情報

構造情報は、Classクラスによって得ることができます。

方法 説明
パブリッククラス<?> []でgetInterfaces() 親インターフェイスのすべてを取得します。
公共パッケージgetPackage() パッケージ、クラスの名前を取得します。
パブリッククラス<?スーパーT> getSuperclass() 継承された親クラス情報にアクセス

例:

public class TestProgramData {
    public static void main(String[] args) {
        Class<?> clazz = MessageImpl.class;
        System.out.println("clazz->"+clazz.getName());
        System.out.println("getPackage()->"+clazz.getPackage().getName());
        System.out.println("getSuperclass()->"+clazz.getSuperclass().getName());
        System.out.println("getInterfaces()->"+ Arrays.toString(clazz.getInterfaces()));

    }
}
interface IMessage{}
interface IMessageData{}
abstract class AbstractMessage implements IMessage,IMessageData{}
class MessageImpl extends AbstractMessage implements IMessage,IMessageData{}

結果:

clazz->com.tx.test.reflection.MessageImpl
getPackage()->com.tx.test.reflection
getSuperclass()->com.tx.test.reflection.AbstractMessage
getInterfaces()->[interface com.tx.test.reflection.IMessage, interface com.tx.test.reflection.IMessageData]
公開された61元の記事 ウォンの賞賛0 ビュー2176

おすすめ

転載: blog.csdn.net/sabstarb/article/details/104701822