初识反射
反射:Reflection
对象------>类信息
反射可以使程序在运行时获取一个类的所有信息(构造器、属性、方法),从而做相应操作。反射其实就是将Java类中的每一个成分映射成一个个Java对象。要想通过反射获取类包含的成分,必须先获取字节码文件对应的Class对象。
Class类表示什么?
很多的人---可以定义一个Person类(有年龄、性别、姓名等)
很多的车---可以定义一个Car类(有发动机、车轮等)
很多的类--Class类(类名、构造方法、属性、方法)
class对象的是 .class文件读入内存时,创建的一个对象
得到Class类的对象有三种方法:
(1)对象.getClass()
(2)类.class
(3)Class.forName("全类名") 最常用的方式
例如:
package com.reflection; import org.junit.Test; public class ReflectionDemo1 { //获取对象的三种方式 @Test public void test1() throws ClassNotFoundException { //通过对象的 getClass()方法 Person p = new Person("小明",6); Class aClass = p.getClass(); //通过 类.class Class personClass = Person.class; //通过 Class.forName() 方法 Class aClass1 = Class.forName("com.reflection.Person"); } }
反射常用方法
代码示例
//反射的常用方法 public class ReflectionDemo02 { /* 调用无参构造函数创建实例化对象 */ @Test public void getInstance1(){ Class<Person> personClass = Person.class; try { Person person = personClass.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } /* 调用有参构造函数创建实例化对象 */ @Test public void getInstance2(){ Class<Person> personClass = Person.class; //获取所有的构造方法 Constructor<?>[] constructors = personClass.getConstructors(); for (int i = 0; i < constructors.length; i++) { System.out.println(constructors[i].getName()); System.out.println(constructors[i].getParameterCount()); } //获取指定的构造方法 try { Constructor<Person> constructor = personClass.getConstructor(String.class, int.class); Person pp = constructor.newInstance("小明", 6); System.out.println(pp); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } //获取类的所有的属性 @Test public void getFields(){ Class<Person> personClass = Person.class; //获取全部 public 修饰的属性 Field[] fields = personClass.getFields(); System.out.println(fields.length); //获取类中声明的全部属性 Field[] declaredFields = personClass.getDeclaredFields(); for (int i = 0; i < declaredFields.length; i++) { //获取属性修饰符 int modifiers = declaredFields[i].getModifiers(); System.out.println(Modifier.toString(modifiers)+": "+declaredFields[i].getName()); } } //获取类中的 包名、类名称、方法 @Test public void getMethods(){ Class<Person> personClass = Person.class; Person pp = new Person("小明",6); //获取包名 System.out.println(personClass.getPackage()); //获取全类名 System.out.println(personClass.getName()); //获取公有(public)方法,包括继承的方法 Method[] methods = personClass.getMethods(); for (int i = 0; i < methods.length; i++) { System.out.println(methods[i]); if (methods[i].getName().equals("toString")){ try { //通过 invoke(Object,parameters) 调用方法 String s = (String) methods[i].invoke(pp); System.out.println(s); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } //获取私有方法,不包括父类继承而来的方法 Method[] declaredMethods = personClass.getDeclaredMethods(); for (int i = 0; i < declaredMethods.length; i++) { System.out.println(declaredMethods[i]); if(declaredMethods[i].getName().equals("set")){ try { //注意,直接调用私有方法会报异常。需要在调用之前,去除访问修饰符的检查 declaredMethods[i].setAccessible(true); Object invoke = declaredMethods[i].invoke(pp); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } } }
本文来自博客园,作者:藤原豆腐渣渣,转载请注明原文链接:https://www.cnblogs.com/javafufeng/p/16801461.html