LoginSignup
2
1

More than 5 years have passed since last update.

java のリフレクトjava.lang.reflect

Last updated at Posted at 2018-11-10

1.1クラスを用意する。

class Person {
private String name = "tony";
private int age = 41;
public Person() {

}
public Person(String name , int age ) {
    this.name = name;
    this.age = age;
}
@Override
public String toString() {
    // TODO 自動生成されたメソッド・スタブ
    return String.format("名前は%s,年齢は%d", name,age);
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public int getAge() {
    return age;
}
public void setAge(int age) {
    this.age = age;
}
}

1.2クラスを取得する方法

private static void demoClassName()  {
    Class<?> class1 = Date.class;
    System.out.println("--Date.class--");
    System.out.println(class1.getName());
    System.out.println(class1.getSimpleName());

    java.util.Date date = new java.util.Date();
    Class<?> class2 = date.getClass();
    System.out.println("--date.getClass()--");
    System.out.println(class2.getName());
    System.out.println(class2.getSimpleName());

    Class<?> class3;
    try {
        class3 = Class.forName("com.yanheng.reflect.Person");
        System.out.println(class3.getName());
        System.out.println(class3.getSimpleName());
    } catch (ReflectiveOperationException e) {
        e.printStackTrace();
    }

}

1.3インスタンスの生成する方法(パラメータなし)

private static void demoCreateInstance() {
    Class<?> class3;
    try {
        class3 = Class.forName("com.yanheng.reflect.Person");

        Person person = (Person) class3.newInstance();
        System.out.println(person.toString());
    } catch (ReflectiveOperationException e) {
        e.printStackTrace();
    }
}

1.4インスタンスの生成する方法(パラメータあり)

private static void demoConstructor() {
    try {
        Class<?> clazz = Class.forName("com.yanheng.reflect.Person");
        Constructor constructor = clazz.getConstructor(String.class , int.class);
        Person person = (Person) constructor.newInstance("阿部",25);
        System.out.println(person.toString());
    } catch (ClassNotFoundException  e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (SecurityException e) {
        e.printStackTrace();
    }
}

1.5インスタンスのメソッド呼ぶ方法

private static void demoMethod() {
    Person person;
    Class<?> clazz;
    Method methodsetName;
    Method methodSetAge;
    try {
        clazz = Class.forName("com.yanheng.reflect.Person");
        person = (Person) clazz.newInstance();
        methodsetName = clazz.getMethod("setName", String.class);
        methodSetAge = clazz.getMethod("setAge", int.class);
        methodsetName.invoke(person, "Tom");
        methodSetAge.invoke(person, 32);
        System.out.println(person.toString());
    } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
        // TODO 自動生成された catch ブロック
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        // TODO 自動生成された catch ブロック
        e.printStackTrace();
    } catch (SecurityException e) {
        // TODO 自動生成された catch ブロック
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        // TODO 自動生成された catch ブロック
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        // TODO 自動生成された catch ブロック
        e.printStackTrace();
    }
}

1.5インスタンスのprivateのfieldを呼ぶ方法

private static void demoLocalVariable() {
    Person person;
    Class<?> clazz;
    Field fieldName;
    Field fieldAge;

    try {
        clazz = Class.forName("com.yanheng.reflect.Person");
        person = (Person) clazz.newInstance();

        fieldName = clazz.getDeclaredField("name");
        fieldName.setAccessible(true);
        fieldName.set(person, "Jack");

        fieldAge = clazz.getDeclaredField("age");
        fieldAge.setAccessible(true);
        fieldAge.set(person, 23);

        System.out.println(person.toString());
    } catch (ClassNotFoundException e) {
        // TODO 自動生成された catch ブロック
        e.printStackTrace();
    } catch (InstantiationException e) {
        // TODO 自動生成された catch ブロック
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        // TODO 自動生成された catch ブロック
        e.printStackTrace();
    } catch (NoSuchFieldException e) {
        // TODO 自動生成された catch ブロック
        e.printStackTrace();
    } catch (SecurityException e) {
        // TODO 自動生成された catch ブロック
        e.printStackTrace();
    }

}

2デザインファクトリの応用

2.1インターフェースとクラス用意

interface Fruit {
    void eat();
}
class Apple implements Fruit {
    @Override
    public void eat() {
        System.out.println("リンゴおいしい");
    }
}

class Lemon implements Fruit {

    @Override
    public void eat() {
        System.out.println("レモン酸っぱいよ");
    }

}

2.2ファクトリ用意

class FruitFactory {
    public static Fruit getInstance(String fruitName) {
        Fruit fruit = null;
        try {
            fruit = (Fruit) Class.forName(fruitName).newInstance();
        } catch (ClassNotFoundException e) {
            // TODO 自動生成された catch ブロック
            e.printStackTrace();
        } catch (InstantiationException | IllegalAccessException e) {
            // TODO 自動生成された catch ブロック
            e.printStackTrace();
        }
        return fruit;
    }
}

2.3ファクトリデモ

private static void demoFactory() {
    String name = "com.yanheng.reflect.Apple";
    Fruit fruit = FruitFactory.getInstance(name);
    fruit.eat();

    name = "com.yanheng.reflect.Lemon";
    Fruit fruit2 = FruitFactory.getInstance(name);
    fruit2.eat();
}

3サンプルコード

4new と reflectの比較

newによるインスタンス生成 :
メリット:早い

reflectによるインスタンス生成:
メリット:拡張性がいい

5Androidのframeworkの応用

activityを起動時にstartActivity(intent);のようにactivityのインスタンスを作成し、onCreateを呼ぶ

フレイムワークはどうやってインスタンスを作った???

コードを見てみましょう
ActivityThreadで

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = appContext.getClassLoader();
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
        StrictMode.incrementExpectedActivityCount(activity.getClass());
        r.intent.setExtrasClassLoader(cl);
        r.intent.prepareToEnterProcess();
        if (r.state != null) {
            r.state.setClassLoader(cl);
        }
    } catch (Exception e) {

AppComponentFactoryで

public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className,
        @Nullable Intent intent)
        throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    return (Activity) cl.loadClass(className).newInstance();
}

ここでクラスの名前でインスタンス生成されました。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1