ToB企服应用市场:ToB评测及商务社交产业平台

标题: java反射 [打印本页]

作者: 丝    时间: 2024-5-14 20:42
标题: java反射
java反射

概念

反射就是java中一种可以获取一个对象的类的方法,类可以通过反射拿到所有方法,并且调用。
获取类方法

获取一个类的方法有三种:
  1. package java_learn;
  2. import java.io.Serializable;
  3. public class Student implements Serializable{
  4.     private static final long serialVersionUID = -5215701594592700115L;
  5.     private String name;
  6.     private String number;
  7.     private String gender;
  8.     public String capt;
  9.     private transient int grade;
  10.     public Student(String name,String number,String gender,int grade) {
  11.         this.name=name;
  12.         this.number=number;
  13.         this.gender=gender;
  14.         this.grade=grade;
  15.         System.out.println("pp");
  16.     }
  17.     public Student(){
  18.         System.out.println("np");
  19.     }
  20.     public void getInformation(){
  21.         System.out.println("name:"+this.name+" number:"+this.number+" gender:"+this.gender+" grade:"+this.grade);
  22.     }
  23.     public void woparam(){
  24.         System.out.println("无参数");
  25.     }
  26.     public void doparam(String pr){
  27.         System.out.println(pr);
  28.     }
  29. }
复制代码
  1. package learn_java;
  2. import learn_java.Students;
  3. public class reflect {
  4.     public  static void  main(String args[]) throws ClassNotFoundException {
  5.         Students A = new Students("capt","11111","male",2);
  6.         //第一种获取Class的方法
  7.         Class clazz1 = A.getClass();
  8.         System.out.println(clazz1);
  9.         //通过静态属性获取Class
  10.         Class clazz2 = Students.class;
  11.         System.out.println(clazz1 == clazz2);
  12.         //通过类的静态方法获得Class
  13.         Class clazz3 = Class.forName("learn_java.Students");
  14.         System.out.println(clazz3 == clazz1);
  15.     }
  16. }
复制代码
注意到所有返回类型是Class类型,该类型的对象中包含了对应类的类名、方法等属性。
反射使用方法

反射中常用的方法有三个:
demo:
  1. package java_learn;
  2. import java.lang.reflect.InvocationTargetException;
  3. public class reflect {
  4.     public  static void  main(String args[]) throws ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, InstantiationException {
  5.         Class clazz3 = Class.forName("java_learn.Student");
  6.         // clazz3.getMethod("woparam", new Class[]{}).invoke(clazz3.newInstance());
  7.         // clazz3.getMethod("doparam", String.class).invoke(clazz3.newInstance(),"capt");
  8.         Class cls = Class.forName("java.lang.Runtime");
  9.         cls.getMethod("exec",String.class).invoke(cls.getMethod("getRuntime").invoke(cls),"open -a Calculator");
  10.     }
  11. }
复制代码
这里需要注意的是
invoke()概述

对于invoke函数的第一个参数:
一般需要先通过getMethod方法得到Method对象,然后该Method对象调用invoke方法,从而实现该Method方法的运行。
同时invoke方法是支持多态机制的,即子类对象也可以通过invoke方法实行父类的方法,父类对象则不可以通过invoke方法实行子类方法。
第二种实例化方法

在上面提到newInstance()在实例化中大概会碰到两种问题,我们已经通过Runtime举例解决了无参数构造函数是私有的这种环境,下面分析要实例化类中不存在无参数构造函数的环境。
获取私有方法、属性

在反射中,使用的类存在两种:
通常是由getMethod()方法来获取public方法,通过getDeclearedMethod()获取类的私有方法。
如许对于之前Runtime类的使用就有了新的方式。我们不需要调用getRuntime()方法来实现对Runtime对象的引用,可以直接使用getDeclearedConstructor()获取其私有的构造器:
  1. Class clazz = Class.forName("java.lang.Runtime");
  2.         Constructor con = clazz.getDeclaredConstructor(null);
  3.         con.setAccessible(true);
  4.         Method ex = clazz.getMethod("exec", String.class);
  5.         ex.invoke(con.newInstance(), "open -a Calculator");
复制代码
这里需要注意的是在获取私有构造方法(属性、构造器)之后,需要使用setAccessible(true),对权限进行修改,将newInstance()判定中的override设置成了true。
总结


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4