Java进阶之反射

来源:互联网 发布:股票历史交易数据查询 编辑:程序博客网 时间:2024/05/29 04:30

反射对于开发是很有帮助的。自己找时间学了学,介绍反射的一些用法;

这里自己写了两个类,用于对后来的结果作实例。把字段贴出来方便看,get和set方法就不贴了。

public class Base {    private String sj;    public String date;}public class Student extends Base {    private String name;    public String id;    private String address;    protected String age;    public Student() {        super();    }    public Student(String name, String id, String address, String age) {        super();        this.name = name;        this.id = id;        this.address = address;        this.age = age;    }}

类的加载

三种方法:

       Student stu=new Student();       Class a=Class.forName("reflectt.Student");       System.out.println(a);//1       System.out.println(stu.getClass());//2       System.out.println(Student.class);//3       结果:       class reflectt.Student       class reflectt.Student       class reflectt.Student

new一个对象

记住我们反射的是一个类名,创建他的对象需要实例化。而且这个类必须有空构造器,否则会报错。这个类我写了两个构造器,看看下面的结果

Object ss=Student.class.newInstance();//得有空构造器System.out.println(ss);结果其实两个构造器都显示了,有一个是空构造器:Student [name=null, id=null, address=null, age=null]

方法介绍

getName() 获取包名下下类名
getSimpleName() 获取不带包名的类名
getFields() 获取此类及其及其父类和接口所能访问的字段,也就是public修饰的
getDeclaredFields()获得该类所有类型修饰的字段

 System.out.println("获取不带包名的类名 "+stu.getClass().getSimpleName()); System.out.println("获取包名下的类的名称"+stu.getClass().getName()); Field []c=stu.getClass().getDeclaredFields(); for(int i=0;i<c.length;i++){  System.out.print("本类字段名称"+c[i].getName()+","); } System.out.println(); Field []c1=stu.getClass().getFields(); for(int i=0;i<c1.length;i++){  System.out.print("可访问的公共字段"+c1[i].getName()+","); }输出结果:获取不带包名的类名 Student获取包名下的类的名称reflectt.Student本类字段名称name,本类字段名称id,本类字段名称address,本类字段名称age,可访问的公共字段id,可访问的公共字段date,

getMethods() 获的该类以及父类和接口所有的公共方法(无序)
getDeclaredMethods() 该类自己的方法,不包含继承的方法(无序)
getConstructors() 该类公共的(public)构造方法(无序)
getDeclaredConstructors 该类所有类型的构造方法 public,protected,默认的,private (无序)
getReturnType()获得方法的返回值类型
getParameterTypes() 获取方法的参数类型

 Method method[]=stu.getClass().getMethods(); for(int i=0;i<method.length;i++){    System.out.print("方法名"+method[i].getName()+",");    System.out.println("方法返回值类型"+method[i].getReturnType().getName());  }  部分结果显示:    方法名toString,方法返回值类型java.lang.String    方法名getAddress,方法返回值类型java.lang.String    方法名getName,方法返回值类型java.lang.String    Constructor []con=stu.getClass().getConstructors();       for(int i=0;i<con.length;i++){           System.out.print("构造器"+con[i].getName()+"参数类型");           //构造器参数的类型           Class[] parameterTypes = con[i].getParameterTypes();           for (Class class1 : parameterTypes) {            System.out.print(class1.getSimpleName()+",");        }           System.out.println();       }  结果显示:构造器reflectt.Student参数类型String,String,String,String,构造器reflectt.Student参数类型

方法的操作

举一个例子:

      Method met=stu.getClass().getMethod("setName", String.class);      //第一个是调用此方法的对象 第二个是 参数 和stu.setName("dcz")一样      met.invoke(stu, "dcz");      //参数没有就不写      Method mer=stu.getClass().getMethod("getName");      //参数没有就不写 也可以写成null       Object invoke = mer.invoke(stu);      System.out.println(invoke);      结果:      dcz

根据反射自己写了个添加条件查询的通用方法,有兴趣的可以研究研究。

//添加条件查询的通用方法public static void print(Object obj) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException{        //获取此类的所有方法        Method method[]=obj.getClass().getDeclaredMethods();        StringBuilder sb=new StringBuilder();        for(int i=0;i<method.length;i++){        //System.out.println(method[i].getName());        //返回值不是void 都是get方法 而且方法名不等于toString              if(!method[i].getReturnType().getSimpleName().equals("void")&&!method[i].getName().equals("toString")){                 //执行get方法 invoke是返回结果   Object invoke = method[i].invoke(obj);   System.out.println(invoke);   if(invoke!=null){    Stringstr=String.valueOf(method[i].getName()).substring(3).toLowerCase();                sb.append(" and "+str+"="+invoke);                 }             }           }    }}
原创粉丝点击