Java反射机制学习

来源:互联网 发布:罗辑思维 人工智能 编辑:程序博客网 时间:2024/06/11 00:39

1.反射机制是什么

反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

2.反射机制能做什么

反射机制主要提供了以下功能:

  • 在运行时判断任意对象所属的类;
  • 在运行时构造任意一个类的对象;
  • 在运行时判断任意一个类所具有的成员变量和方法;
  • 在运行时调用任意一个对象的方法;
  • 生成动态代理;

3.反射机制的相关API

通过一个对象获得完整的包名和类名

package reflect;import java.io.Serializable;/** * 获取包名类名, */public class TestReflect1 {    public static void main(String[] args) throws ClassNotFoundException {        Demo demo = new Demo();        System.out.println(demo.getClass().getName());    }}class Demo implements Serializable {}

输出结果:reflect.Demo

实例化Class类对象

package reflect;import java.io.Serializable;/** * 实例化Class类对象 */public class TestReflect1 {    public static void main(String[] args) throws ClassNotFoundException {        Class demo1 = null;        Class demo2 = null;        Class<?> demo3 = null;        //实例化class类对象的三种方式,        demo1 = Class.forName("reflect.Demo");//一般采用这种方式        demo2 = new Demo().getClass();        demo3 = Demo.class;        System.out.println(demo1);        System.out.println(demo2);        System.out.println(demo3);    }}class Demo implements Serializable {}

输出结果:
class reflect.Demo
class reflect.Demo
class reflect.Demo

获取一个对象的父类与实现的接口

package reflect;/** * 获取一个对象的父类与实现的接口 */public class TestReflect2 {    public static void main(String[] args) {        try {            Class<?> clazz = Class.forName("reflect.Demo");            Class<?> parentClass = clazz.getSuperclass();//父类的类对象            System.out.println("父类为:"+parentClass.getName());            Class<?>[] intes = clazz.getInterfaces();            for (Class<?> c : intes) {                System.out.println("接口为:"+c.getName());            }        } catch (ClassNotFoundException e) {            e.printStackTrace();        }    }}

输出结果:
父类为:java.lang.Object
接口为:java.io.Serializable

获取某个类中的全部构造函数

通过反射机制实例化一个类的对象

package reflect;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;/** * 获取某个类中的全部构造函数,并通过反射,实例化一个类对象 */public class TestReflect3 {    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException {        Class<?> class1 = Class.forName("reflect.User");        //第一种方法,实例化默认构造器        User user = (User) class1.newInstance();        user.setName("zhangsan");        user.setAge(25);        System.out.println(user);        //第二种方法,获取全部的构造函数,使用构造函数复制        Constructor<?>[] constructors = class1.getConstructors();        //查看每个构造方法需要的参数        for (int i=0; i<constructors.length; i++) {            Class<?>[] clazzs = constructors[i].getParameterTypes();            System.out.print("constructors[" + i + "] (");            for (int j = 0; j < clazzs.length; j++) {                if (j == clazzs.length - 1)                    System.out.print(clazzs[j].getName());                else                    System.out.print(clazzs[j].getName() + ",");            }            System.out.println(")");        }        User user2 = (User) constructors[0].newInstance("李四", 26);        System.out.println(user2);        User user3 = (User) constructors[1].newInstance("Lisi");        System.out.println(user3);        user3.setAge(24);        User user4 = (User) constructors[2].newInstance();        user4.setName("Lisi");        user4.setAge(20);        System.out.println(user4);    }}class User {    private int age;    private String name;    public User() {        super();    }    public User(String name) {        super();        this.name = name;    }    public User(String name, int age) {        super();        this.name = name;        this.age = age;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    @Override    public String toString() {        return "User{" +                "age=" + age +                ", name='" + name + '\'' +                '}';    }}

输出结果为:
User{age=25, name=’zhangsan’}
constructors[0] (java.lang.String,int)
constructors[1] (java.lang.String)
constructors[2] ()
User{age=26, name=’李四’}
User{age=0, name=’Lisi’}
User{age=20, name=’Lisi’}

获取某个类的全部属性

package reflect;import java.io.Serializable;import java.lang.reflect.Field;import java.lang.reflect.Modifier;import java.util.Arrays;/** * 获取某个类的全部属性 */public class TestReflect4 implements Serializable {    public static void main(String[] args) throws ClassNotFoundException {        Class<?> clazz = Class.forName("reflect.User");        //获取属性        Field[] field = clazz.getDeclaredFields();        System.out.println(Arrays.toString(field));        for (int i = 0; i < field.length; i++) {            // 权限修饰符            int mo = field[i].getModifiers();            String priv = Modifier.toString(mo);            // 属性类型            Class<?> type = field[i].getType();            System.out.println(priv + " " + type.getName() + " " + field[i].getName() + ";");        }    }}

输出结果为:
[private int reflect.User.age, private java.lang.String reflect.User.name]
private int age;
private java.lang.String name;

获取某个类的全部方法

package reflect;import java.lang.reflect.Method;import java.lang.reflect.Modifier;/** * 获取某个类的全部方法 */public class TestReflect5 {    public static void main(String[] args) throws ClassNotFoundException {        Class<?> clazz = Class.forName("reflect.User");        Method[] methods = clazz.getMethods();        for (int i=0; i<methods.length; i++) {            Class<?> returnType = methods[i].getReturnType();            Class<?>[] paras = methods[i].getParameterTypes();            int mo = methods[i].getModifiers();            System.out.print(Modifier.toString(mo)+" ");//权限修饰符            System.out.print(returnType.getName()+" ");//返回值类型            System.out.print(methods[i].getName()+" ");//方法名称            System.out.print("(");            for (int j = 0; j < paras.length; ++j) {                System.out.print(paras[j].getName() + " " + "arg" + j);                if (j < paras.length - 1) {                    System.out.print(",");                }            }            Class<?> exce[] = methods[i].getExceptionTypes();            if (exce.length > 0) {                System.out.print(") throws ");                for (int k = 0; k < exce.length; ++k) {                    System.out.print(exce[k].getName() + " ");                    if (k < exce.length - 1) {                        System.out.print(",");                    }                }            } else {                System.out.print(")");            }            System.out.println();        }    }}

输出结果为:
public java.lang.String toString ()
public java.lang.String getName ()
public void setName (java.lang.String arg0)
public int getAge ()
public void setAge (int arg0)
public final void wait () throws java.lang.InterruptedException
public final void wait (long arg0,int arg1) throws java.lang.InterruptedException
public final native void wait (long arg0) throws java.lang.InterruptedException
public boolean equals (java.lang.Object arg0)
public native int hashCode ()
public final native java.lang.Class getClass ()
public final native void notify ()
public final native void notifyAll ()

通过反射机制调用某个类的方法

package reflect;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;/** * 通过反射机制调用某个类的方法 */public class TestReflect6 {    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {        Class<?> clazz = Class.forName("reflect.TestReflect6");        Method method1 = clazz.getMethod("reflect1");        method1.invoke(clazz.newInstance());        Method method2 = clazz.getMethod("reflect2", int.class, String.class);        method2.invoke(clazz.newInstance(), 20, "张三");    }    public void reflect1() {        System.out.println("Java 反射机制 - 调用某个类的方法1");    }    public void reflect2(int age, String name) {        System.out.println("Java 反射机制 - 调用某个类的方法2");        System.out.println("age -> " + age + ". name -> " + name);    }}

输出结果为:
Java 反射机制 - 调用某个类的方法1
Java 反射机制 - 调用某个类的方法2
age -> 20. name -> 张三

通过反射机制操作某个类的属性

package reflect;import java.lang.reflect.Field;/** * 通过反射机制操作某个类的属性 */public class TestReflect7 {    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {        Class clazz = Class.forName("reflect.User");        User user = (User) clazz.newInstance();        Field field = clazz.getDeclaredField("name");        Field field1 = clazz.getDeclaredField("age");        field1.setAccessible(true);        field.setAccessible(true);        field.set(user, "张三");        field1.set(user, 20);        System.out.println(user);    }}

输出结果为:
User{age=20, name=’张三’}

反射机制的动态代理

类加载器

在java中有三种类类加载器。
* Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。
* Extension ClassLoader 用来进行扩展类的加载,一般对应的是jrelibext目录中的类
* AppClassLoader 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器。

public class TestReflect8 {    public static void main(String[] args) {        TestReflect8 testReflect8 = new TestReflect8();        //获取类加载器        System.out.println(testReflect8.getClass().getClassLoader().getClass().getName());    }}

输出结果:
sun.misc.Launcher$AppClassLoader

package reflect;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;/** * 反射机制的动态代理 */public class TestReflect8 {    public static void main(String[] args) {        MyInvocationHandler demo = new MyInvocationHandler();        Subject sub = (Subject) demo.bind(new RealSubject());        String info = sub.say("张三", 24);        System.out.println(info);    }}//项目接口interface Subject {    public String say(String name, int age);}//真实项目class RealSubject implements Subject {    @Override    public String say(String name, int age) {        return name + "  " + age;    }}class MyInvocationHandler implements InvocationHandler {    private Object object;    public Object bind(Object object) {        this.object = object;        return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this);    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        Object temp = method.invoke(this.object, args);        return temp;    }}

输出结果:
张三 24

4.反射机制的应用实例

在泛型为Integer的ArrayList中存放一个String类型的对象。

package reflect;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Member;import java.lang.reflect.Method;import java.util.ArrayList;/** * 反射机制的应用实例 * 1.在泛型为Integer的ArrayList中存放一个String类型的对象。 */public class TestReflect9 {    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {        ArrayList<Integer> list = new ArrayList<>();        list.add(1);        list.add(2);        Method method = list.getClass().getMethod("add", Object.class);        method.invoke(list, "Java反射机制实例");        System.out.println(list);        System.out.println(list.get(2));    }}

输出结果为:
[1, 2, Java反射机制实例]
Java反射机制实例

通过反射取得并修改数组的信息

package reflect;import java.lang.reflect.Array;/** * 通过放射修改数组的信息 */public class TestReflect10 {    public static void main(String[] args) {        int[] temp = {1, 2, 3, 4, 5};        Class<?> demo = temp.getClass().getComponentType();        System.out.println("数组的类型: " + demo.getName());        System.out.println("数组的长度: " + Array.getLength(temp));        System.out.println("数组的第一个元素: " + Array.get(temp, 0));        Array.set(temp, 0, 100);        System.out.println("修改之后数组第一个元素为: " + Array.get(temp, 0));    }}

输出结果为:
数组的类型: int
数组的长度: 5
数组的第一个元素: 1
修改之后数组第一个元素为: 100

通过反射机制修改数组的大小

package reflect;import java.lang.reflect.Array;/** * 通过反射机制修改数组的大小 */public class TestReflect11 {    public static void main(String[] args) {        int[] temp = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };        int[] newTemp = (int[]) arrayInc(temp, 15);        print(newTemp);        String[] atr = { "a", "b", "c" };        String[] str1 = (String[]) arrayInc(atr, 8);        print(str1);    }    //修改数组大小    public static Object arrayInc(Object obj, int len) {        Class<?> arrType = obj.getClass().getComponentType();        Object newArr = Array.newInstance(arrType, len);        int co = Array.getLength(obj);        System.arraycopy(obj, 0, newArr, 0, co);        return newArr;    }    //打印    public static void print(Object obj) {        Class<?> c = obj.getClass();        if (!c.isArray()) {            return;        }        System.out.println("数组的长度: "+Array.getLength(obj));        for (int i = 0; i<Array.getLength(obj); i++) {            System.out.print(Array.get(obj, i) + " ");        }        System.out.println();    }}

输出结果为:
数组的长度: 15
1 2 3 4 5 6 7 8 9 0 0 0 0 0 0
数组的长度: 8
a b c null null null null null

将反射机制应用于工厂模式

package reflect;import sun.java2d.pipe.AlphaPaintPipe;/** * 将反射机制应用与工厂模式 * 对于普通的工厂模式当我们在添加一个子类的时候,就需要对应的修改工厂类。 当我们添加很多的子类的时候,会很麻烦。 * 现在我们利用反射机制实现工厂模式,可以在不修改工厂类的情况下添加任意多个子类。 * 但是有一点仍然很麻烦,就是需要知道完整的包名和类名,这里可以使用properties配置文件来完成。 *  */public class TestReflect12 {    public static void main(String[] args) {        fruit fruit = Factory.getInstance("reflect.Apple");        if (fruit != null) {            fruit.eat();        }    }}interface fruit {    public void eat();}class Apple implements fruit {    @Override    public void eat() {        System.out.println("Apple");    }}class Orange implements fruit {    public void eat() {        System.out.println("Orange");    }}class Factory {    public static fruit getInstance(String className) {        fruit f = null;        try {            f = (fruit) Class.forName(className).newInstance();        } catch (InstantiationException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            e.printStackTrace();        }        return f;    }}

输出结果为:
Apple

原创粉丝点击