Java中的反射Reflection
反射知识:
获取类型模板对象有三种方式:
1. 通过对象调用Object类中的getClass()方法来获取Class对象。
2. 利用Class类中的forName( String className)方法来获取class对象。
注:其中的className即为类全名(类全名 =包名.类名)。
3. 通过类型名来获取class对象。
代码如下:
package day11.javaAdvance.exercise.reflection.Class;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ClassTest1 {
public static void main(String[] args) throws Exception {
/*
* 获取类型模板对象有三种方法:
*/
// 1.通过对象调用getClass方法获取Class对象
Student stu = new Student("wangwang", 4);
// 类型模板对象
Class c1 = stu.getClass();
System.out.println("1..." + c1);
System.out.println("^^^" + c1.getName());
// 2.利用Class对象来获取
Class c2 = Class.forName("day11.javaAdvance.exercise.reflection.Class.Student");//方法:forName("类全名");
System.out.println("2..." + c2);
// 3.通过类型名来获取
Class c3 = Student.class;
System.out.println("3..." + c3);
/*
* 获得此类的属性方法
*/
Field f[] = c1.getFields();
for (int i = 0; i < f.length; i++) {
System.out.println("属性有:" + f[i].getName());
}
}
}
class Student {
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
private void show() {
}
public void print() {
System.out.println("name=" + name + "," + "age=" + age);
}
}
通过反射方法动态来获取类中的方法和构造函数(五步)
1. 先获取类型模板对象:Class c=Student.class;
2. 通过类型模板对象来获取构造函数: Class arr[]={}; Constructor con=c.getDeclaredConstructor(arr);
3. 调用构造方法创建对象:Object obj1[]={}; Object obj=con.newInstance(obj1);
System.out.println(obj);
4. 获取方法:Method m=c.getMethod("show", arr);
5. 利用Mehtod对象调用方法invoke
Object o=m.invoke(obj, obj1);
package day11.javaAdvance.exercise.reflection.Class;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
/*
* 重点: 通过反射方法动态来获取类中的方法以及构造函数(五步)。
*/
public class ClassTest3 {
public static void main(String[] args) throws Exception {
// 1. 获得类型模板对象
Class cc = Studentd.class;
// 2.通过类型模板对象来获取构造方法
Class arrl[] = {};
// 在java.lang.reflect 类 Constructor<T>包中
Constructor cons = cc.getDeclaredConstructor(arrl);
// 3.调用构造方法创建实例
Object arr2[] = {};
Object obj1 = cons.newInstance(arr2);
System.out.println("%%% " + obj1);
// 4.获取方法
/*
* public Method getMethod(String name, Class<?>... parameterTypes)
*它反映此Class 对象所表示的类或接口的指定公共成员方法。
*/
Method m = cc.getMethod("show", arrl);
//5.invoke method 调用方法:
/*
*public Object invoke(Object obj,Object... args) 对带有指定参数的指定对象调用由此
* Method 对象表示的底层方法。
*/
Object obj = m.invoke(obj1, arr2);
Constructor[] con = cc.getConstructors();
for (int i = 0; i < con.length; i++) {
System.out.println("@@@ " + con[i]);
}
}
}
class Studentd {
public String name;
private int age;
public Studentd(String name, int age) {
this.name = name;
this.age = age;
}
public Studentd() {
}
public void show() {
System.out.println("~~~~呵呵.....");
}
private void show1() {
System.out.println("Hello!.....");
}
public void print() {
System.out.println("name=" + name + "," + "age=" + age);
}
}
package day11.javaAdvance.exercise.reflection.Class;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;
public class ClassTest4 {
public static void main(String[] args) {
Biz1 b = new Biz1();
b.finteat();
}
}
class Biz1 {
Animal animal = (Animal) AnimalFactory.getObject("impl");
public void finteat() {
animal.eat();
}
}
class AnimalFactory {
static Properties pro = new Properties();
static {
try {
pro.load(new FileInputStream("config2.properties"));// 文件放在根目录下
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static Object getObject(String name) {
Object obj = null;
String className = pro.getProperty(name);// name即是key键值,className即是value值。
try {
Class c = Class.forName(className);
Class[] cl = {};
Constructor con = c.getDeclaredConstructor(cl);
Object[] obj1 = {};
obj = con.newInstance(obj1);
System.out.println("类全名是:" + obj);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return obj;
}
}
interface Animal1 {
public void eat();
}
class Dog1 implements Animal {
public void eat() {
System.out.println("dog eatting ....");
}
}
class Cat1 implements Animal {
public void eat() {
System.out.println("cat eatting....");
}
}
其中的配置文件在config2.properties文件中。
配置文件中是键值对,其中的key=impl,value分别是Dog1类和Cat1类,以类全名方式赋值。其内容是:
impl= day11.javaAdvance.exercise.reflection.Class.Dog1
#impl=day11.javaAdvance.exercise.reflection.Class.Cat1
这样我们只要传递键值,即可得到配置文件中的value值即是代码中的:String className = pro.getProperty(name);得到的className即是value值。
使用配置文件的好处:不需在源代码中去修改代码,只需在配置文件中修改,这样很好体现了java的封装性这一特点。

浙公网安备 33010602011771号