一、原理
简介:
- 应用在一些通用性比较高的代码中
- 大多数使用反射来实现 框架
- 在框架开发中,都是基于配置文件开发的
在配置文件中,可以通过反射,得到类中的所有内容,可以让类中的某个方法来执行
Tomcat 对外提供了接口,为了扩展功能,由开发者来实现具体请求和应答处理
Java反射机制是在运行状态中, 对任意一个类(class),都能知道这个累的属性和方法
对于任意一个对象,可以调用他的任意一个方法和属性
动态获取信息+动态动态调用对象的方法的功能=java语言的反射机制[对类的解剖]
反射技术:加载字节码文件,获取并调用其中的内容
对一个类文件进行解剖,只需要拿到该类的字节码文件对象即可.
配置变化的参数信息
原理:
- 把Java文件保存到本地硬盘 .java
- 编译Java文件,成.class文件
- 使用JVM,把class文件通过类加载器加载到内存中
- class文件在内存中,使用class类来表示对象
- 反射:首先,获取class类,其次,得到里面所有内容
- 如何获取?
属性:通过一个类 Filed
构造方法:通过一个类 Constructor
普通方法:通过一个类Method
得到class类的3种方式:
类名.class
任何对象都具备 静态属性.class,来获取对应的class对象
相对简单,但是必须明确到类中的静态成员–>不够扩展对象.getClass()
必须明确具体的类 并创建对象,麻烦[不建议]使用Class.forName(“路径”)
知道 类的字符串名称 就可以获得该类
方便,扩展性强
二、使用反射操作无参构造方法
//操作无参构造方法
@Test
public void test1() throws Exception {
//得到class
Class c3 = Class.forName("cn.itcast.test06.Person");
//得到Person类的实例
Person p = (Person) c3.newInstance();
p.setId(1500);
System.out.println(p.getId());
}
对一个对象实例化,可以new ,不使用new的话,可以如下操作:
//得到class
Class c3 = Class.forName("cn.itcast.test06.Person");
//得到Person类的实例
Person p = (Person) c3.newInstance();
三、使用反射操作有参构造方法
//操作有参构造方法
@Test
public void test2() throws Exception {
//得到class
Class c1 = Class.forName("cn.itcast.test06.Person");
//使用有参构造方法
//c1.getConstructors();//获取所有的构造方法
//穿肚有参数的构造方法里面的参数类型,类型使用class形式传递
Constructor cs = c1.getConstructor(String.class,String.class);
//通过有参数的构造方法,设置值,创建Person实例
Person p1 = (Person) cs.newInstance("jingvjing","100");
System.out.println(p1.getId()+":"+p1.getName());
}
四、使用反射操作name属性
@Test
//操作name属性
public void test3() throws Exception {
try{//得到class
Class c3 = Class.forName("cn.itcast.test06.Person");
//得到name属性
//c3.getDeclaredFields();//获取所有属性
//得到person实例
Person p11 = (Person)c3.newInstance();
Field f1 = c3.getDeclaredField("name");
//设置可以操作私有属性,不让操作时,使用这个
f1.setAccessible(true);
//设置name值[实例,值]
f1.set(p11, "wujing");
System.out.println(p11.getName());
}catch(Exception e) {
e.printStackTrace();
}
}
五、使用反射操作普通方法
//操作方法
@Test
public void test4() throws Exception {
//得到class
Class c4 = Class.forName("cn.itcast.test06.Person");
//得到实例
Person p12 = (Person)c4.newInstance();
//得到普通方法
//c4.getDeclaredMethods();//得到所有方法 【方法名,方法值】
Method m1 =c4.getDeclaredMethod("setName", String.class);
//执行setName方法,设置值 【类的实例,设置值】
m1.invoke(p12,"aoao");
System.out.println(p12.getName());
}
反射操作静态方法时,类名.静态方法,不需要实例。代码为:m1.invoke(null,”aoao”);
package cn.itcast.reflect.dmeo;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import cn.itcast.bean.Person;
public class ReflectDemo {
public static void main(String[] args) throws Exception {
// getClassObject();
// getClassObject2();
// getClassObject3();
// getFieldDemo();
// getMethodDemo();
// getMethodDemo1();
// getMethodDemo22();
}
//调用有参方法
public static void getMethodDemo22() throws Exception {
Class c = Class.forName("cn.itcast.bean.Person");
Method m = c.getMethod("parammethod", String.class,int.class);//方法必须是公有的
Object obj = c.newInstance();
m.invoke(obj, "one",80);
}
//调用无参方法
private static void getMethodDemo1() throws Exception{
Class c = Class.forName("cn.itcast.bean.Person");
Method m = c.getMethod("show", null);
Constructor con = c.getConstructor();
Object obj = con.newInstance();
m.invoke(obj, null);
}
//获取所有公有方法+获取本类中的方法
private static void getMethodDemo() throws Exception {
Class c = Class.forName("cn.itcast.bean.Person");
Person p = (Person) c.newInstance();
Method[] m = c.getMethods();//获取所有公有方法
Method[] m1 = c.getDeclaredMethods();//获取本类中的方法,包含私有
for(Method ms :m1) {
System.out.println(ms);
}
}
//获取字节码中的字段
private static void getFieldDemo() throws Exception {
Class c = Class.forName("cn.itcast.bean.Person");
Field field = null;
field = c.getDeclaredField("age");//只获取本类,但包含私有
//对私有字段访问取消权限检查
field.setAccessible(true);
Object obj = c.newInstance();
//设置值
field.set(obj, 89);
Object o = field.get(obj);
System.out.println(o);
}
//知道 类的字符串名称 就可以获得该类
//方便,扩展性强
private static void getClassObject3() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
Class c1 = Class.forName("cn.itcast.bean.Person");
System.out.println(c1);
Constructor con = c1.getConstructor(int.class,String.class);
Person p = (Person) con.newInstance(20,"ioo");
System.out.println(p.getAge()+":"+p.getName());
}
//任何对象都具备 静态属性.class,来获取对应的class对象
//相对简单,但是必须明确到类中的静态成员-->不够扩展
private static void getClassObject2() throws InstantiationException, IllegalAccessException {
Class c1 = Person.class;
Class c2 = Person.class;
Person p = (Person) c1.newInstance();
p.setAge(123);
p.setName("ann");
System.out.println((c1==c2)+"\r\n"+p.getAge()+p.getName());
}
//必须明确具体的类 并创建对象,麻烦[不建议]
private static void getClassObject() {
Person p = new Person();
Class c = p.getClass();
Person p1 = new Person();
Class c1 = p1.getClass();
System.out.println(c1==c);
}
}