JAVA中的反射

反射机制是什么

Java反射指的是在运行状态时,能够获取类的属性和方法或者修改类运行时行为的过程。

java.lang.Class类提供了很多方法用于获取元数据、检查和改变类运行时的行为。

Java的反射主要涉及java.lang和java.lang.reflect包下的类。

反射机制能做什么

反射机制主要提供了以下功能: 

  • 在运行时判断任意一个对象所属的类;
  • 在运行时构造任意一个类的对象;
  • 在运行时判断任意一个类所具有的成员变量和方法;
  • 在运行时调用任意一个对象的方法;
  • 生成动态代理。

JDK为我们提供了那些反射机制中的类:

java.lang.Class;                

java.lang.reflect.Constructor;

 java.lang.reflect.Field;        

java.lang.reflect.Method;

java.lang.reflect.Modifier;

反射的使用

通过反射机制动态一个对象获得完整的包名和类名

java.lang.Class类

java.lang.Class主要提供了以下两个功能:

  • 提供方法用于访问运行期间类的元数据;
  • 提供方法用于检查和修改类的运行时行为;

怎样获取Class对象

有三种方式,如下:

Class类的forName()方法,动态加载,运行时,开始装入类, 并做类的静态初始化

对象的getClass()方法,静态加载(编译时已加载)

.class语法, 静态加载(编译时已加载)

java.lang.Class类常用方法

Method

Description

1) public String getName()

返回类名

2) public static Class forName(String className)throws ClassNotFoundException

加载类并返回Class对象

3) public Object newInstance()throws InstantiationException,IllegalAccessException

创建实例对象

4) public boolean isInterface()

判断是否是接口

5) public boolean isArray()

判断是否是数组

6) public boolean isPrimitive()

判断是否是原始数据类型

7) public Class getSuperclass()

返回父类Class引用

8) public Field[] getDeclaredFields()throws SecurityException

返回类的成员属性字段数组

9) public Method[] getDeclaredMethods()throws SecurityException

返回类的方法数组

10) public Constructor[] getDeclaredConstructors()throws SecurityException

返回类的构造方法数组

11) public Method getDeclaredMethod(String name,Class[] parameterTypes)throws NoSuchMethodException,SecurityException

返回类中指定参数类型的方法

public static void main(String[] args)  throws Exception{

              Class<?> clazz = ArrayList.class;

              System.out.println("className = "+clazz.getName());

              System.out.println("is interface = " + clazz.isInterface());

              System.out.println("is array = " + clazz.isArray());

//           获取父类的Class对象

              Class<?> superClass = clazz.getSuperclass();

              //获取类实现的接口

              Class<?> [] interfaces = clazz.getInterfaces();

              //获取本类所定义的所有属性,不包含父类属性

              Field []fileds = clazz.getDeclaredFields();

              //获取类所定义的所有属性,包含父类的属性

              fileds = clazz.getFields();

              //根据属性名称获取属性,不会从父类获取,若当前类没有则返回null

              Field ageFiled = clazz.getDeclaredField("age");

              //根据属性名称获取属性,如果父类有也会返回

              ageFiled = clazz.getField("age");

              //获取本类所定义的所有的方法,不包含父类

              Method []ms = clazz.getDeclaredMethods();

              //获取类所定义的所有的方法,包含父类的方法

              ms = clazz.getMethods();

              //根据方法名和方法参数获取方法,不包含父类

              Method m = clazz.getDeclaredMethod("add",Object.class);

              //根据方法名和方法参数获取方法,包含父类

              m = clazz.getMethod("add",Object.class);

              //获取所有构造方法

              Constructor<?> []cons = clazz.getConstructors();

              //根据参数类型获取指定的构造方法

              Constructor<?> con = clazz.getConstructor(int.class);

       }

动态调用构造方法创建对象

public static void main(String[] args)  throws Exception{

              Class<?> clazz = ArrayList.class;

              //调用不带参数的构造方法创建对象

              List list = (List)clazz.newInstance();

              //调用int类型的参数创建对象

              //先获取到构造方法

              Constructor<?> cons = clazz.getConstructor(int.class);

              list = (List) cons.newInstance(10);             

       }

动态的操作属性

     

  public static void main(String[] args) throws Exception{

              //动态创建一个对象

              System.out.println(Human.class.getName());

              Object h = Class.forName("com.deng.Human").newInstance();

              //找到name属性

              Class<?> clazz = h.getClass();

              Field f = clazz.getDeclaredField("name");

              //若属性是private的,则必须要设置其可访问,才可以设置和取值

              //若是非private的,则不需要

              f.setAccessible(true);

              //设置属性

              f.set(h, "张三");        

              //获取属性的值

              System.out.println(f.get(h));

       }

动态调用方法:

原文地址:https://www.cnblogs.com/dengcl/p/7682753.html