Java反射reflect学习

2021年11月24日 阅读数:4
这篇文章主要向大家介绍Java反射reflect学习,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。
恰巧前段时间面试的时候问到了Java的反射,当时答得不是很好,正好抽空从新温习下,本文只讲解下经过反射获取到类的属性、构造方法、方法,关于类加载器(ClassLoader)将在其余文章中有具体介绍,本文不做介绍。

Class.forName()用法详解

主要功能
Class.forName(xxx.xx.xx)返回的是一个类。
Class.forName(xxx.xx.xx)的做用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段。 
A a = (A)Class.forName(“pacage.A”).newInstance();//这和你 A a = new A(); 是同样的效果。

首先,经过Class获取类的字节码
Class clazz = Class.forName("clazz.Test01");
一、获取类的属性
  //获取类的属性对象,须要填写属性对象的名称
  Field f1=c.getField("name");//只能获取public的对象
  Field f2=c.getDeclaredField("age");//能够获取到private的对象,这很吊吧
  f2.setAccessible(true);//若是属性是私有的,那么就须要设置可访问
二、利用Constructor建立对象
Constructor c = clazz.getConstructor(null);//获取无参的构造函数
Constructor c = clazz.getConstructor(String.class);//获取参数为String的构造函数
Constructor c = clazz.getConstructor(String.class, int.class);//获取参数为String,int的构造函数
Constructor c = clazz.getDeclaredConstructor(List.class);//获取隐藏为private的构造函数
c.setAccessible(true);//暴力反射
建立对象的另一种途径,反射出类的无参构造函数并建立对象
Class clazz = Class.forName("com.marer.reflect.Person");
Person p = (Person) clazz.newInstance();
暴力反射获取类的隐藏构造函数:Constructor.setAccessible(true);
三、利用Method 获取类方法
Method[] methods = clazz.getDeclaredMethods();////获取自身全部的方法(private、public、protected,和访问权限无关),不包括继承的
methods = clazz.getMethods();//获取包括自身和继承(实现)过来的全部的public方法
Method m = clazz.getMethod("t2",String.class);//获取指定方法t2

四、反射调用t2方法
Object o = clazz.newInstance();
m.invoke(o,"123");

package clazz;

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

public class TestClazz {

    public static void main(String[] args) throws Exception{
        try {
            Class<?> clazz = Class.forName("clazz.Test01");
            //获取本类的全部方法,存放入数组
            Method[] methods = clazz.getDeclaredMethods();////获取自身全部的方法(private、public、protected,和访问权限无关),不包括继承的
            methods = clazz.getMethods();//获取包括自身和继承(实现)过来的全部的public方法
            Method m = clazz.getMethod("t2",String.class);
            Object o = clazz.newInstance();
            m.invoke(o,"123");
            System.out.println("-------------------------");
            for (Method method : methods) {
                System.out.println("方法名:"+method.getName());
                //获取本方法全部参数类型,存入数组
                Class<?>[] getTypeParameters = method.getParameterTypes();
                if(getTypeParameters.length==0){
                    System.out.println("此方法无参数");
                }
                for (Class<?> class1 : getTypeParameters) {
                    String parameterName = class1.getName();
                    System.out.println("参数类型:"+parameterName);
                }
                System.out.println("****************************");
            }

            Constructor<?>[] constructors = clazz.getConstructors();
            for (Constructor constructor : constructors) {
                System.out.println("构造器名:"+constructor.getName());
            }

            Constructor<?> c1 = clazz.getConstructor(null);
            System.out.println("构造器名:"+c1.getName());
            Test01 o1 = (Test01)c1.newInstance();
            System.out.println(o1);
            Constructor<?> c2 = clazz.getConstructor(String.class, String.class);
            System.out.println("构造器名:"+c2.getName());
            Test01 o2 = (Test01)c2.newInstance("1", "1");
            System.out.println(o2);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

}