什么是反射:
反射:
在程序运行中,对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意方法和属性;
这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
简而言之,反射就2个作用,
1、可以在程序运行中获取任意类的属性、方法、构造器、注解等信息;
2、可以在程序运行时调用类中的任意的属性和方法,包括私有。【这块有疑问,应该是对象而不是任意类】
在开发中我们一般在代理模式、工具类(比如DbUtils、JSON)、框架中使用。
反射涉及到的类说明:
1、Class:
这是反射的核心类,也是一个泛型类,java规定任意类型都有Class对象。常用方法,参考jdk1.8API
1.getAnnotation(Class annotationClass)
Returns this element`s annotation for the specified type if such an annotation is present,else null.
获取指定类型的注解对象,找到就返回否则就返回null.
2.getAnnotations()
Returns annotations that are present on this element.
返回对应类上的所有注解对象。
3.getClassLoader()
Returns the class loader for the class.
返回类的加载器对象。
4.getDeclaredFields()
Returns an array of Field objects reflecting all the fields declared by the class or interface represented by this Class object.
获取对应类中所有的属性,无论什么访问修饰符,但不包括继承的属性
5.getFields()
Returns an array containing Field objects reflecting all the accessible public fields of the class or interface represented by this Class object.
获取对应类中所有的公共属性,也包括继承来的公共属性。
6.getDeclaredMethods()
Returns an array containing Method objects reflecting all the declared methods of class or interface represented by this Class object,including public,protected,default(package)access,and private methods,but excluding inherited methods.
获取对应类中的所有方法,无论什么访问修饰符,但是不包括继承来的方法。
7.getMethods()
Returns an array containing Method objects reflecting all the public methods of the class or interface represented by this Class object ,including those declared by the class or interface and those inherited from superclasses and superinterfaces.
获取对应类中的所有公共方法,也包括继承来的公共方法。
8.newInstance()
Creates a new instance of the class represented by the Class object.
创建对应类的对象。
以上就是Class类的常用方法,没列出的方法参考java的API。
反射的使用:
以Dog类为题进行学习Class的使用:
public class Dog{ private int id; public String name; protected String type; private void eat(){ System.out.println(“一般狗都喜欢啃骨头”); } private void eat(int count,String food){ System.out.println(“隔壁家的狗狗吃了”+count+”个”+food); } public void show(){ System.out.println(“编号:”+id+”,名称:”+name+”,类型:”+type); } }
class对象创建的三种方式:
public static void main(String[] args) throws Exception{ Class<Dog> clsl; //第一种方式 clsl=Dog.class; //第二种方式 clsl = (class<Dog>) Class.forName(“cn.code404.domain.Dog”); //第三种方式 clsl = (Class<Dog>) new Dog().getClass(); System.out.println(clsl.getName()); }
获取属性和方法:
Class<Dog> class1 = Dog.class; //获取指定类中的所有属性,不包括继承的属性 Field[] arrDF = class1.getDeclaredFields(); for(Field f:arrDF){ //输出字段名称 System.out.println(f.getName()); } System.out.println(“****************”); //获取指定类中的所有公共字段,包括继承的属性 Field[] arrF = class1.getFields(); for(Field f:arrF){ System.out.println(f.getName()); } System.out.println(“****************”); //获取指定类中所有的方法,不包括继承 Method[] arrDM = class1.getDeclaredMethods(); for(Method m:arrDM){ System.out.println(m.toString()); } System.out.println(“****************”); //获取指定类中所有公共方法,包括继承 Method[] arrM = class1.getMethods(); for(Method m:arrM){ System.out.println(m.toString()); }
调用私有方法:
public static void main(String[] args) throws Exception{ Class<Dog> cls = Dog.class; //执行私有方法不带参数 //一、获取要执行的方法对象 Method method1 = cls.getDeclaredMethod(“look”); //创建对应类的对象 Dog dog = cls.newInstance(); //设置忽略访问校验,true:不进行访问校验,false:进行访问校验 method1.setAccessible(true); //执行私有方法 method1.invoke(dog); //二、执行私有带参数的方法 //1、获取方法对象 Method method2 = cls.getDeclaredMethod(“eat”,int.class,String.class); //2、设置忽略访问校验 method2.setAccessible(true); //3、执行私有方法 method2.invoke(dog,2,”猫”); }
以上是反射的基本调用