###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();
}
ここでクラスの名前でインスタンス生成されました。