Java基础-反射机制

什么是反射?
在程序运行期间,可以动态加载类,可以动态获取类的信息【属性、方法】,可以动态的调用对象的方法
java.lang.reflect.*;

所有的类型或类可以有java.lang.class类来管理

类通过对象来管理

Class 类 类型,其对象用来管理指定类或类型的相关信息

例如:要管理java.lang.String 类,则需要获取Class类的对象

获取类 类型

获取Class类 类型的对象(Class类的对象)有3种方式

1 动态加载类 Class obj = static forName(包名.类名);

Class<?> obj=Class.forName(className);

2 通过Object对象的getClass()方法

例1 “abc”.getClass();

例2 Person p1 = new Person();  Class c1=p1.getClass();

3 通过数据类型(基础+引用)的静态属性 .class

例 int.class

Class类的方法

String getName(); 获取类名(含包名)

String getSimpleName(); 获取类名

例子 Class aa;  aa.getName();

例子2-动态加载类

String className=args[0];//完整的包名.类名 如java.lang.String

Class<?> obj(obj是一个类)=Class.forName(className);

//Object o(o才是对象)=obj.newInstance();

String show = odj.getName;

println(show);

or

if(o instanceOf Integer){...}

=================

Class c

c是Class类的对象

c也是一种具体的类

Class<?> obj(obj是一个类)=Class.forName(className);

Object o(o才是对象)=obj.newInstance();

//obj.newInstance()调用默认构造器

Office oc=(Office)o;//Office是一个接口,o可以取值word、excel等实现了Office接口的类

//Office和Object有一个共同的儿子word或女儿excel或...

oc.start();

//反射和多态结合,业务更加灵活..

//即动态加载类、动态创建该类的对象..

示例代码:

public class ReflectionTest {

    public static void main(String[] args) {
        //通过args接收参数
        try {
            String className = args[0];//必须是完整路径java.*...
            Class<?> class1=Class.forName(className);
            Object object=class1.newInstance();
            Office office=(Office) object;
            office.start();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

}

=================

常用的反射:
类类型
构造器类型
属性
方法
====

获取给定类中的所有构造器:
1加载类,并获取Class类的对象(目标:管理指定的类)
Person.class;
new Person.getClass();
Class.forName("Person");
2调用Class类提供的getConstructors()来获取所有的public权限的构造
器,获取的所有构造器会组成一个数组,由
java.lang.reflect.Constructor来管理
tem.getDeclaredConstuctors()--反射所有
3遍历
3-1 获取构造器的名称 tem.getName()
3-2 获取构造器的参数 tem.getParametertTypes()
3-3 获取形式参数 t.getSimpleName()

获取属性:
1、同上
2、java.lang.reflect.Field//字段反射类
调用Class类提供的getFields()--【只看public】方法,获取所有属性并
组成一个数组,【但getDeclaredFields()-反射所有权限的属性】
3、遍历,显示 【class】getType()属性的类型 getName()属性的名称-+

获取方法:
1、同上
2、java.lang.reflect.Method
getMethods()--含父类、public
getDeclaredMethods()--不含父类、可以private
3、遍历
[String]getName();
[Class[]]getParameterTypes()
getSimpleName

可变参数:
public int add(int ... a);
public int add(int[] b);

==========================

反射的应用:

构造器、方法、属性、数组的反射

1、构造器的反射

先搞一个对象

import java.util.Date;

public class Person {
    // 属性
    private String name;
    private Date birthday;

    // 构造器
    public Person() {
    }

    private Person(String name) {
        super();
        this.name = name;
    }

    public Person(String name, Date birthday) {
        super();
        this.name = name;
        this.birthday = birthday;
    }

    // 访问器、设定器
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    // 功能方法
    public int add(int a, int b) {
        return 9527 + a + b;
    }

    public void show() {
        System.out.println("show方法被执行");
    }

    private void show(String s) {
        System.out.println("show-s方法被执行");
    }

    public double area(double d1, double d2) {
        return d1 + d2;
    }

    @Override
    public String toString() {
        return "姓名:" + name + "	生日" + birthday;
    }
}

再看看简单的应用:

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectUSED {

    public static void main(String[] args) {
        // 1 默认构造器的反射
        // 要求被反射的对象有正宗的默认构造器 通过newInstance()来实现
        try {
            Class class1 = Class.forName("jee.反射.反射的应用.Person");
            Object object = class1.newInstance();
            System.out.println(object.toString());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        // 2 带参数的构造器
        // 先【Class】getConstuctor(Class..paramTypes)来获取Constructor对象
        // 后【Constructor】newInstance(Object..paramTypes)来创建对象
        try {
            // 加载类
            Class class1 = Class.forName("jee.反射.反射的应用.Person");
            // 获取带一个String类型的构造器
            Constructor cst1 = class1.getDeclaredConstructor(new Class[] { String.class });
            // Constructor cst2 = class1.getConstructor(new Class[]
            // {String.class });
            // (可选)放开权限,当构造器是private是也可以通过反射使用
            cst1.setAccessible(true);// 否则报异常:权限不对
            // 创建对象
            Object object = cst1.newInstance(new Object[] { "刘德华" });
            // 关闭权限(可选)
            cst1.setAccessible(false);
            // 显示
            System.out.println(object);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        // 3 方法的反射,注意权限问题
        try {
            Class class1 = Class.forName("jee.反射.反射的应用.Person");
            Object object = class1.newInstance();
            // 无参
            Method method = class1.getMethod("show", new Class[] {});
            // 有参
            Method method2 = class1.getDeclaredMethod("show", new Class[] { String.class });
            // 可变参数
            // Method method3 = class1.getMethod("show()", new Class[] {int[].class });
            method.invoke(object, new Object[] {});
            method2.setAccessible(true);
            method2.invoke(object, new Object[] { "show的实参" });

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }

        // ==============

    }

}

///////////////////////////////练习题

/**
 * 2016年5月24日下午12:42:41
 */

package d518Reflect;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
 interface Office {
    void start();
}

class Word implements Office {
    @Override
    public void start() {
        System.out.println("Word start");
    }
}

class Excel implements Office {
    @Override
    public void start() {
        System.out.println("Excel start");
    }
}

class PowerPoint implements Office {
    @Override
    public void start() {
        System.out.println("PowerPoint start");
    }
}

class Person {
    private int id;
    private String name;

    public Person() {
    }

    public Person(String name) {
        super();
        this.name = name;
    }

    public Person(int id, String name) {
        super();
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "编号" + id + "	姓名" + name;
    }

    public void add(int i, int j) {
        System.out.println("i+j=" + (i + j));
    }

    private void add2(int i, int j) {
        System.out.println("i+j=" + (i + j));
    }

    public int add3(int i, int j) {
        return i + j;
    }
}

public class ReflectTest {

    public static void main(String[] args)
            throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException,
            SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
        {
            System.out.println("练习1:动态获取类类型的名称");
            // 模拟参数args[0]为className
            // 注意:完整的className包含包名
            String className = "java.lang.String";
            // 1 动态获取类类型对象及其名称
            System.out.println("完整类名:" + Class.forName(className).getName());
            System.out.println("简单类名:" + Class.forName(className).getSimpleName());
        }
        {
            System.out.println("
练习2:动态加载类类型,动态绑定多个类对象的方法");
            String className = "d518Reflect.Excel";
            // 加载 类
            Class<?> class1 = Class.forName(className);
            // 创建 类对象
            Object object = class1.newInstance();
            // 对象还原
            Office office = (Office) object;// Office 和 Excel间是实现关系,若没有关系,报错
            // 动态绑定
            office.start();
        }
        {
            System.out.println("
练习3:遍历 构造器");
            String className = "d518Reflect.Person";
            Class<?> class1 = Class.forName(className);
            Constructor<?>[] con = class1.getDeclaredConstructors();
            for (Constructor<?> tem : con) {
                System.out.print("构造器名称:" + tem.getName() + "(");
                Class<?>[] types = tem.getParameterTypes();
                for (Class<?> temp : types) {
                    System.out.print(" " + temp.getSimpleName() + " ");
                }
                System.out.println(")");
            }
        }
        {
            System.out.println("
练习4:遍历 属性");
            String className = "d518Reflect.Person";
            Class<?> class1 = Class.forName(className);
            Field[] fields = class1.getDeclaredFields();
            for (Field field : fields) {
                System.out.println(field.getType().getSimpleName() + "	" + field.getName());
            }
        }
        {
            System.out.println("
练习5:遍历 方法");
            String className = "d518Reflect.Person";
            Class<?> class1 = Class.forName(className);
            Method[] ms = class1.getDeclaredMethods();
            for (Method md : ms) {
                System.out.print(md.getName() + "(");
                Class<?>[] types = md.getParameterTypes();
                for (Class<?> type : types) {
                    System.out.print(" " + type.getSimpleName() + " ");
                }
                System.out.println(")");

            }
        }
        {
            System.out.println("
练习6:构造器 反射");
            String className = "d518Reflect.Person";
            Class<?> class1 = Class.forName(className);
            Object obj = class1.newInstance();// 默认构造器 直接使用
            Constructor<?> con = class1.getDeclaredConstructor(String.class);// 1
                                                                                // 带参
            Object obj2 = con.newInstance("张三");// 2 对象
            System.out.println(obj);
            System.out.println(obj2);
        }
        {
            System.out.println("
练习7:属性 反射");
            String className = "d518Reflect.Person";
            Class<?> class1 = Class.forName(className);
            Field field = class1.getDeclaredField("id");
            Object obj1 = class1.newInstance();
            System.out.println("修改前" + obj1);
            field.setAccessible(true);
            Object value = 8;
            field.set(obj1, value);
            System.out.println(obj1);
        }
        {
            System.out.println("
练习8:方法 反射");
            String className = "d518Reflect.Person";
            Class<?> class1 = Class.forName(className);
            Object obj = class1.newInstance();
            Method add = class1.getDeclaredMethod("add", int.class, int.class);
            add.invoke(obj, 2, 3);// 调用方法时,指明 对象
        }
        {
            System.out.println("
练习9:数组 反射");
            // // 一维数组
            // Class<?> class1 = int.class;//指定类型
            // Object arr = Array.newInstance(class1, 5);//创建数组
            // System.out.println("一维数组:");
            // for (int i = 0; i < 5; i++) {
            // int j = i * 3;
            // Array.set(arr, i, j);//设置值
            // System.out.print(Array.get(arr, i)+" ");//获取值
            // }
            // 多维数组
            // 准备一个指定大小的二维数组
            int size[] = new int[] { 5, 10 };
            // 准备数组存放数组的类型
            Class type = int.class;
            Object array = Array.newInstance(type, size);
            // 设置值
            Array.set(Array.get(array, 0), 0, 66);
            // 访问值
            System.out.println(Array.get(Array.get(array, 0), 0));
        }

    }

}
原文地址:https://www.cnblogs.com/qixiawentang/p/5504430.html