一、反射
1.什么是反射?
2.为什么使用反射?
3.如何获取反射类Class?
4.Class反射类中常用的方法?
5.获取反射Method对象
6.Method类中具有的方法。
7.获取反射Field对象
8.Field类中常用的方法。
1.什么是反射?
--反射是框架设计的灵魂。是在类运行期间,把类中成员抽取为其他类的过程。
学过的框架:mybaties持久化框架、springmvc框架 mvc框架、spring框架。
2.为什么使用反射?
为了解决在运行期,对某个实例一无所知的情况下,如何调用其方法或属性。
比如:1.spring框架中只需要传入类的路径,spring框架就会帮你创建类的对象。
2.Idea通过反射获取类中所有的method方法对象,以提示框的形式列出。
3.如何获取反射类Class?
提供了三种模式:
第一种:通过类名.class属性
Class<Student> aClass = Student.calss;
第二种:通过类路径获取
Class aClass = Class.forName("导入获取的类");
第三种:通过对象名获取
Student student = new Student();
Class aClass = student.getClass();
public class Test01 {
public static void main(String[] args) throws Exception{
//1.通过类名.calss属性
Class<Student> studentClass = Student.class;
//2.通过类路径获取
Class<?> aClass = forName("com.wjy.ref01.Student");
//3.通过对象名获取反射类
Student student = new Student();
Class<? extends Student> aClass1 = student.getClass();
}
}
4.Class反射类中常用的方法?
1.根据反射类获取实例对象:newInstance()--得到反射类的类对象
2.得到反射类上的注解对象:getAnnotation()
public static void main(String[] args) throws Exception{
Class<Student> aClass = Student.class;
//通过newInstance()创建对象--得到实例
Student student = aClass.newInstance();
System.out.println(student);
//获取反射类上的注解对象--反射是在运行时得到的
MyAnnotation annotation = aClass.getAnnotation(MyAnnotation.class);
System.out.println(annotation.value());
}
5.获取反射Method对象
本类:
getDeclaredMethods():得到本类中所有的方法
getDeclaredMethod("方法名",参数类型):获取本类中指定的方法对象
本类以及父辈类(直到Object类):
getMethods():获取本类以及父辈类中public修饰的方法
getMethod("方法名",参数类型):获取本类及父辈类指定public修饰的方法
方法对象:
1.getDeclaredMethods():得到本类中所有的方法对象
2.getDeclaredMethod("方法名",参数类型):获取本类中指定方法的对象
3.getMethods():获取本类以及父辈类中所有的方法对象
4.getMethod("方法名",参数类型):获取本类以及父辈类中指定方法的对象
package com.wjy.ref01;
import java.lang.reflect.Method;
public class Test03 {
public static void main(String[] args) throws Exception {
//通过类名.calss获取类的Class对象
Class<Student> sClass = Student.class;
//得到本类中定义的所有Method类对象
Method[] declaredMethods = sClass.getDeclaredMethods();
for(Method method : declaredMethods){
System.out.println(method);
}
System.out.println("--------------------");
//获取本类中指定的方法对象
Method show = sClass.getDeclaredMethod("show", Integer.class);
System.out.println(show);
System.out.println("~~~~~~~~~~~~~~~~~~~~");
//获取本类以及父辈类中所有public方法的对象
Method[] methods = sClass.getMethods();
for (Method method : methods){
System.out.println(method);
}
System.out.println("========================");
//获取本类以及父辈类中指定的方法对象
Method method = sClass.getMethod("equals", Object.class);
System.out.println(method);
}
}
6.Method类中具有的方法。
.invoke(Object对象,参数值):为获取指定的方法对象赋值
.setAccessible(true):设置允许访问私有成员
public class Test04 {
public static void main(String[] args) throws Exception{
//根据类路径获取对象
//为泛型通配符
Class<?> aClass = Class.forName("com.wjy.ref01.Student");
//得到实例对象
Object o = aClass.newInstance();
//指定方法对象
Method method = aClass.getMethod("say", Integer.class);
//执行该方法,并返回执行结果。
// 参数1:执行该方法的对象,参数2:执行该方法时,传入的参数赋值
Object res = method.invoke(o, 25);
System.out.println(res);
System.out.println("-----------------------");
Method toke = aClass.getDeclaredMethod("toke", Integer.class);
//暴力反射--允许私有访问
toke.setAccessible(true);
//执行该方法,并返回执行结果。
Object invoke = toke.invoke(o, 26);
System.out.println(invoke);
}
}
Student.java 执行结果
7.获取反射Field对象
获取本类指定的属性对象:getDeclaredFiled("指定类对象名")
获取本类中所有的属性对象:getDeclaredFileds()
获取本类和父类中public修饰指定的属性:getFiled("指定类对象名")
获取本类和父类中所有public的属性:getFileds()
8.Field类中常用的方法。
set(Object对象,值):为属性赋值
getName():获取属性名
getAnnotation(注解类包.class):获取属性上的注解对象
package com.wjy.ref01;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test05 {
public static void main(String[] args) throws Exception {
Class<Student> studentClass = Student.class;
Student student = studentClass.newInstance();
System.out.println(student);
Field name = studentClass.getDeclaredField("name");
name.set(student,"刘德华");
System.out.println(student);
Field age = studentClass.getDeclaredField("age");
age.setAccessible(true);
age.set(student,20);
System.out.println(student);
System.out.println("-------------");
Field[] declaredFields = studentClass.getDeclaredFields();
for (Field f :declaredFields){
System.out.println(f.getName());
MyAnnotation annotation = f.getAnnotation(MyAnnotation.class);
String value = annotation.value();
System.out.println(value);
}
}
}
9.案例
package com.wjy.ref02;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.Properties;
import java.util.Random;
public class Test02 {
public static void main(String[] args) throws Exception {
//1.加载属性文件
InputStream resourceAsStream = Test02.class.getClassLoader().getResourceAsStream("ref02.properties");
//2.通过属性类Properties读取属性文件
Properties properties = new Properties();
properties.load(resourceAsStream);
//3.属性类读取属性文件中指定的key的值--读取到的类的路径名
String className = properties.getProperty("className");
//4.根据类路径得到反射对象
Class<?> aClass = Class.forName(className);
//5.得到实例--根据反射创建对象
Object o = aClass.newInstance();
System.out.println(o);
//6.为属性赋值--获取本类中所有属性对象
Field[] declaredFields = aClass.getDeclaredFields();
for(Field field:declaredFields){
//允许访问私有
field.setAccessible(true);
//为属性赋值--为属性设置随机的值
field.set(o,new Random().nextInt(1000)+"");
}
System.out.println(o);
}
}
通过上面的例子 我们指定反射是i运行时,对原来类一无所知的情况下执行
10.总结
1.获取Class反射类的方式有三种:
①类名.calss属性:Class<Student> aClass = Student.class;
②类路径获取:Class aClass1 = Class.forName("导入类");
③对象名获取:Student student = new Student();
Class aClass2 = studnet.getClass();
2.Class类中常用的方法:
①根据反射类得到实例对象:.newInstance();
②得到反射类上的注解对象:.getAnnotation(注解类包.class);
3.获取Method方法类对象:(方法有:有参无参构造、set、get、toString)
①.getDeclaredMethods():得到本类中所有的方法
②.getDeclaredMethod("要获取的方法名",参数类型):得到本类中指定的方法
父辈类:一直到Object最顶层类
③.getMethods():获取本类以及父辈类中public修饰的所有方法
④.getMethod("方法名",参数类型):获取本类以及父辈类中指定的public修饰的所有方法
4.Method类对象中常用的方法
①.invoke(Object对象,参数值)
②.setAccessible(true)设置允许访问私有成员
5.获取Filed属性对象的方式;
①.getDeclaredFileds():获取本类中所有的属性对象
②.getDeclaredFiled("属性名"):获取本类指定的属性对象
③.getFileds():获取本类以及父辈类中public修饰的所有属性
④.getFiled("属性名"):获取本类以及父辈中指定的public修饰的所有属性
6.Filed类中常用的方法;
①.set(Object对象,值):为属性赋值
②.getName():获取属性名
③.getAnnotation(注解类包.class):获取属性上的注解对象