java反射

反射

定义

java核心技术卷1中的定义:能够分析类能力的程序称为反射。

反射:将类的各个部分封装为其它对象,这就是反射机制。

百度:反射就是根据给出的类名(字符串)来生成对象

java反射

  • 好处:

    • 1.在程序运行时期操纵对象。

    Idea程序在运行期间,当你定义一个Integer的对象a,a.就会展示所有的方法名

java反射

Integer类在Idea运行期间就被ClassLoader加载到内存中,当点击.时只需及那个Method数组中的名字显示出来就可以了。

  • 2.降低程序耦合性。

    举例:加载数据库驱动

    编译期报错

    Class.forName("com.mysql.jdbc.Driver");//加载数据库驱动  

    直接报错

    new com.mysql.jdbc.Driver()//创建driver对象,加载数据库驱动

    获取Class类对象的方式

    1. class.forName("全限定类名")

    2. 类名.class

    3. 实例.getClass()

      Class类的方法:

      关于Field

      返回类型 方法名 描述
      Field[] getFields() 获取公有成员变量
      Field getField(String name) 通过公有变量名获取公有对象
      Field[] getDeclaredFields() 获取全部变量
      Field getDeclaredField(String name) 通过变量名获取变量

      关于Constructor

    返回类型 方法名
    Constructor[] getConstructors()
    Constructor getConstructor(类... parameterTypes)
    Constructor[] getDeclaredConstructors()
    Constructor getDeclaredConstructor(类... parameterTypes)

    关于Methond

    返回类型 方法名
    Methond[] getMethods()
    Methond getMethod(String name, 类<?>... parameterTypes)
    Methond[] getDeclaredMethods()
    Methond getDeclaredMethod(String name, 类<?>... parameterTypes)

java反射

java反射

如果是私有构造器:

constructor.setAccessible(true);

成员变量相关:

java反射

反射的应用场景:框架的底层

在用框架的时候我们将需要配置的东西写在配置文件中,将对象创建的主动权交出去。(控制反转Ioc)

IoC中最基本的Java技术就是“反射”编程。通俗的说,反射就是根据给出的类名(字符串)来生成对象。这种编程方式可以让应用在运行时才动态决定生成哪一种对象。反射的应用是很广泛的,像Hibernate、Spring中都是用“反射”做为最基本的技术手段。

通过文本的配置文件进行应用程序组件间相互关系的配置,而不用重新修改并编译具体的代码。

简单模拟:实现一个类可以在运行时动态创建任意对象,并且执行任意方法。

Person类:

package com.zyb.pric;


public class Person {
   public int id;
   private String name;

    public Person() {
    }

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

    public int getId() {
        System.out.println("getId被执行");
        return id;

    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }


}

package com.zyb.pric;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

public class ReflectDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        //1.加载配置文件

        Properties pro = new Properties();
        ClassLoader classLoader = ReflectDemo.class.getClassLoader();
        InputStream p = classLoader.getResourceAsStream("pro.properties");
        pro.load(p);

        //2.获取文件中的数据
        String className = pro.getProperty("className");
        String methodName = pro.getProperty("methodName");

        //3.加载该类进内存
        Class cl = Class.forName(className);
        //4.创建对象
        Object obj = cl.newInstance();
        Field declaredField = cl.getDeclaredField("id");
        declaredField.set(obj,545);
        //5.获取方法对象
        Method method = cl.getMethod(methodName);
        //执行方法
        Object invoke = method.invoke(obj);
        System.out.println(invoke);

    }
}

pro.properties

className=com.zyb.pric.Person
methodName=getId

读取类中的所有相关信息:

package com.zyb.pric;


import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Scanner;

public class ReflectionTest {

    public static void main(String[] args) {
        //read class name from command line args or user input
        String name;
        if(args.length>0){
            name=args[0];
        }else{
            Scanner in = new Scanner(System.in);
            System.out.println("Enter class name (e.g. java.util.Date):");
            name=in.next();
        }
        try{
            //print class name and superclass name (if!=Object)
            Class cl=Class.forName(name);
            Class supercl=cl.getSuperclass();
            String modifiers= Modifier.toString(cl.getModifiers());
            System.out.print(" class "+name);
            if(supercl!=null&&supercl!=Object.class) System.out.print(" extends "
                +supercl.getName());
            System.out.print("\n{\n");
            printConstructors(cl);
            System.out.println();
            printMethods(cl);
            System.out.println();
            printFields(cl);
            System.out.println("}");
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }
        System.exit(0);
    }
    /**
     * Prints all constructors of a class
     * @param cl a class
     */
    public static void printConstructors(Class cl){
        Constructor[] constructors = cl.getDeclaredConstructors();
        for (Constructor c: constructors) {
            String name=c.getName();
            System.out.print("  ");
            String modifiers = Modifier.toString(c.getModifiers());
            if(modifiers.length()>0) System.out.print(modifiers+" ");
            System.out.print(name+"(");

            //print parameter types
            Class[]paramTypes = c.getParameterTypes();
            for (int i = 0; i < paramTypes.length; i++) {
                if(i>0) System.out.print(", ");
                System.out.print(paramTypes[i].getName());
            }
            System.out.println(");");
        }
    }


    /**
     * Prints all methods of a class
     * @param cl a class
     */
    public static void printMethods(Class cl){
        Method[] methods = cl.getDeclaredMethods();
        for (Method m:methods){
            Class resType = m.getReturnType();
            String name=m.getName();

            System.out.print("  ");
            //print modifiers,return type and method name
            String modifiers= Modifier.toString(m.getModifiers());
            if(modifiers.length()>0) System.out.print(modifiers+" ");
            System.out.print(resType.getName()+" "+name+"(");
            //print parameter types

            Class[] paramTypes = m.getParameterTypes();
            for (int i = 0; i <paramTypes.length ; i++) {
                if(i>0) System.out.print(", ");
                System.out.print(paramTypes[i].getName());

            }
            System.out.println(");");
        }
    }

    /**
     * Prints all fields of a class
     * @param cl a class
     */
    public static void printFields(Class cl){
        Field[] fields = cl.getDeclaredFields();
        for (Field f: fields) {
            Class<?> type = f.getType();
            String name = f.getName();
            System.out.print("  ");
            String modifiers = Modifier.toString(f.getModifiers());
            if(modifiers.length()>0) System.out.print(modifiers+" ");
            System.out.println(type.getName()+" "+name+";");
        }
    }
}

输入java.lang.Double的运行结果:

java反射

上一篇:opencl(5)缓存对象


下一篇:环形均分纸牌-七夕祭