java-反射
Posted 哎哟我去a
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java-反射相关的知识,希望对你有一定的参考价值。
反射:
Java反射机制指的是在Java程序运行状态中,对于任何一个类,都可以获得这个类的所有属性和方法;对于给定的一个对象,都能够调用它的任意一个属性和方法。这种动态获取类的内容以及动态调用对象的方法称为反射机制。通过反射我们可以获得该类的构造方法、成员变量,成员方法;
1、获得某个对象的属性。
通过getClass()方法获得某个对象的类,然后实例化一个Field对象,接收类声明的属性,最后通过get()方法
获得该属性的实例,注意,这里的属性必须为公有的,否则将会报illegalAeeessException的异常。
2、获得某个类的静态属性。
首先根据类名获得该类,同获得某个对象的属性一样,通过实例化一个Field对象,接收该类声明的属性,不同的是,由于属性是静态的,所以直接从类中获取。
3、执行某对象的方法。
同样要先获得对象的类,然后配置类的数组,并把它作搜索方法的条件。通过getMethod()方法,得到要执行的方法。执行该invoke方法,该方法中执行的是owner对象中带有参数args的方法。返回值是一个对象。
4、执行某个类的静态方法。
基本的原理和“执行某个类的方法”相同,不同点在于method.invoke(null,args),这里的第一个参数是null,因为调用的是静态方法,所以不需要借助owner就能运行。
5、新建类的实例。我们利用执行带参数的构造函数的方法来新建一个实例。如果不需要参数,可以直接使用newoneClass.newlnstaneeO来实现嘲。同样要先得到要构造的实例的类,然后构造参数的类数组,构造器是通过getConstructor(argsClass)得到的,最后使用newlnstanee(args)方法新建一个实例。
知识点:
getxxxs():获取所有公共的属性、方法
getDeclaredxxxs():获取所有的成员属性、方法;私有、公有、受保护,不包括继承
getDeclaredxxx():获取私有的xxx;
代码准备:准备 一个实体
public class Dept implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private Integer deptno; private String dname; private String loc; private List<Emp> listEmp; public String role; public Dept(Integer deptno, String dname, String loc) { this.deptno = deptno; this.dname = dname; this.loc = loc; } public Dept(Integer deptno, String dname) { super(); this.deptno = deptno; this.dname = dname; } private Dept(Integer deptno) { super(); this.deptno = deptno; System.out.println(this.deptno ); } public Dept() { super(); } public Integer getDeptno() { return deptno; } public void setDeptno(Integer deptno) { this.deptno = deptno; } public String getDname() { return dname; } public void setDname(String dname) { this.dname = dname == null ? null : dname.trim(); } public String getLoc() { return loc; } public void setLoc(String loc) { this.loc = loc == null ? null : loc.trim(); } public List<Emp> getListEmp() { return listEmp; } public void setListEmp(List<Emp> listEmp) { this.listEmp = listEmp; } @Override public String toString() { return "Dept [deptno=" + deptno + ", dname=" + dname + ", loc=" + loc + ", listEmp=" + listEmp + "]"; } public String getRole() { return role; } public void setRole(String role) { this.role = role; } private String getDep(String parm) { return parm; } public static void main(String[] args) { System.out.println("main方法执行了。。。"); } }
编码测试
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import com.supers.system.domain.Dept; public class Tests { static String clazzName="com.supers.system.domain.Dept"; @SuppressWarnings({ "rawtypes", "unchecked" }) public static void main(String[] args) throws Throwable, Throwable { // getConstructor(); // getField (); // getMethod(); depMain(); } private static void depMain() throws Throwable { Class clazz=Class.forName(clazzName); Method method= clazz.getMethod("main", String[].class); Object obj=method.invoke(null, (Object)new String[]{"a","b","c"}); //System.out.println(obj); } private static void getMethod() throws Throwable { String clazzName="com.supers.system.domain.Dept"; Class clazz=Class.forName(clazzName); System.out.println("************获取所有公有方法********************"); Method[] methods= clazz.getMethods(); for (int i = 0; i < methods.length; i++) { System.out.println(methods[i]); } System.out.println("************获取所有方法********************"); Method[] methodss=clazz.getDeclaredMethods(); for (int i = 0; i < methodss.length; i++) { System.out.println(methodss[i]); } System.out.println("************获取公有方法并调用********************"); Method method=clazz.getMethod("setRole", String.class); System.out.println(method); Object obj = clazz.getConstructor().newInstance(); //实例化一个Student对象 method.invoke(obj, "总裁"); method=clazz.getMethod("getRole", null); Object result2= method.invoke(obj, null); System.out.println(result2); System.out.println("************获取私有方法并调用********************"); Object mobj = clazz.getConstructor().newInstance(); method=clazz.getDeclaredMethod("getDep", String.class); method.setAccessible(true);//解除限定 Object result=method.invoke(mobj, "总监"); System.out.println(result); } private static void getField() throws Throwable, Throwable { String clazzName="com.supers.system.domain.Dept"; try { Class clazz=Class.forName(clazzName); System.out.println("************获取所有公有的字段********************"); Field[] fieldArray = clazz.getFields(); for(Field f : fieldArray){ System.out.println(f); } System.out.println("************获取所有的字段********************"); fieldArray=clazz.getDeclaredFields(); for (int i = 0; i < fieldArray.length; i++) { System.out.println(fieldArray[i]); } System.out.println("************获取所有公有字段并调用********************"); Field f=clazz.getField("role"); Object obj=clazz.newInstance();//=====>> Dept dept=new Dept(); f.set(obj, "总经理"); Dept dep=(Dept)obj; System.out.println(dep.getRole()); System.out.println("************获取私有字段并调用********************"); f=clazz.getDeclaredField("dname"); Object objdname=clazz.newInstance(); f.setAccessible(true); f.set(objdname, "副总经理"); Dept dep2=(Dept)objdname; System.out.println(dep2.getDname()); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void getConstructor() throws Throwable, Throwable{ //获取构造方法 String className = "com.supers.system.domain.Dept"; Class clazz=null; try { clazz = Class.forName(className); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("**********************所有公有构造方法*********************************"); Constructor[] conArray = clazz.getConstructors(); for(Constructor c : conArray){ System.out.println(c); } //2 getDeclaredConstructors() System.out.println("**********************受保护、默认、公有、私有*********************************"); conArray=clazz.getDeclaredConstructors(); for (int i = 0; i < conArray.length; i++) { System.out.println(conArray[i]); } System.out.println("*****************获取公有、无参的构造方法*******************************"); Constructor con = clazz.getConstructor(null); //1>、因为是无参的构造方法所以类型是一个null,不写也可以:这里需要的是一个参数的类型,切记是类型 //2>、返回的是描述这个无参构造函数的类对象。 System.out.println("con = " + con); //调用构造方法 Object obj = con.newInstance(); System.out.println(obj.toString()); System.out.println("*****************读取私有构造方法*******************************"); con=clazz.getDeclaredConstructor(Integer.class); System.out.println(con); //调用构造方法 con.setAccessible(true);//暴力访问(忽略掉访问修饰符) obj=con.newInstance(20); //System.out.println(obj.); } public static void Class() { //反射类 String className = "com.supers.system.domain.Dept"; try { //获取类对象的第一种方式 Class pClass1 = Class.forName(className); //1.获取类对象 //获取类对象的第二种方式 Class pClass2 = Dept.class; // 2.获取构造器对象 //获取类对象的第三种方式 Class pClass3 = new Dept().getClass(); // 3 获取对象 System.out.println(pClass1==pClass2);//输出true System.out.println(pClass1==pClass3);//输出true } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
尽管反射机制带来了极大的灵活性及方便性,但反射也有缺点。反射机制的功能非常强大,但不能滥用。在能不使用反射完成时,尽量不要使用,原因有以下几点:
1、性能问题。
Java反射机制中包含了一些动态类型,所以Java虚拟机不能够对这些动态代码进行优化。因此,反射操作的效率要比正常操作效率低很多。我们应该避免在对性能要求很高的程序或经常被执行的代码中使用反射。而且,如何使用反射决定了性能的高低。如果它作为程序中较少运行的部分,性能将不会成为一个问题。
2、安全限制。
使用反射通常需要程序的运行没有安全方面的限制。如果一个程序对安全性提出要求,则最好不要使用反射。
3、程序健壮性。
反射允许代码执行一些通常不被允许的操作,所以使用反射有可能会导致意想不到的后果。反射代码破坏了Java程序结构的抽象性,所以当程序运行的平台发生变化的时候,由于抽象的逻辑结构不能被识别,代码产生的效果与之前会产生差异。
参考学习网址:https://blog.csdn.net/sinat_38259539/article/details/71799078
以上是关于java-反射的主要内容,如果未能解决你的问题,请参考以下文章
使用反射在外部JAR / CLASS上调用包含Hibernate事务的方法(Java EE)