Java_反射_基础
1.什么是反射 ?
2.如何获取反射类Class
3.如何获取属性类Field
4.如何获取方法类Method
5.如何获取构造类Constructor
6.如何获取注解类Annotation
7.写个例子 : 模拟SpringIOC功能
1. 什么是反射?--框架设计的灵魂
(1) 框架 : 就是一种半成品 好处:可以提高开发效率,使代码更加简洁
(2) 反射: 把类中成员抽取为其他类的过程叫做反射
2. 如何获取反射类Class
(1) Class.forName("全路径"); 通 过类的全类名字符串来获取
例子 : Spring框架<bean id="" class="类的全路径"/> --可以获取类对象--Class-->类对象
(2) 类名.class; 通过类名来获取
例子 :mybatis框架 session.getMapper(StudentDao.class)
(3) 对象名.getClass(); 通过对象类获取
当知道该类对象时,可以通过对象来获取反射类
package com.qy143.demo01;
public class demo01 {
public static void main(String[] args) throws ClassNotFoundException {
// 获取Class类的方式
// 1. 通过类的全类名字符串来获取
Class aClass = Class.forName("com.qy143.demo01.Student");
// 2. 通过类名来获取
Class bclass = Student.class;
// 3. 对象
Student s=new Student();
Class cClass= s.getClass();
// 思考: 上面这些方式获取到的Class对象的地址是否一样?
System.out.println(aClass==bclass); // == 比较引用地址
System.out.println(aClass==bclass); // 三者皆为true
System.out.println(cClass==bclass); // 任何一个类的反射类对象只有一个
}
}
class Student{
private String name;
private int age;
public void show(){
System.out.println("++++++++++++++++++++show+++++++++++++++++++++");
}
public Student() {
}
}
3. 如何通过反射类获取对应的类对象
例子:
package com.qy143.demo2;
public class Test02 {
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
Class<Student> aClass = Student.class;// 得到Student的反射类对象
Student student = aClass.newInstance(); // 通过反射类得到对应的类对象
System.out.println(student);
}
}
class Student{
private String name;
private int age;
public void show(){
System.out.println("++++++++++++++++++++show+++++++++++++++++++++");
}
public Student() {
}
4. 获取Field类的方式
Field getDeclaredField(String name) : 获取当前类中指定名称的属性对象 (不包括父类)
Field getDeclaredFields() :获取当前类中所有的属性对象(不包括父类)
Field getField(String name) :获取指定public修饰的属性名的Field对象[包含父类的属性]
Field getFields() : 获取所有public修饰的属性对象[包含父类的属性]
例子:
package com.qy143.demo03;
import java.lang.reflect.Field;
import java.util.concurrent.Callable;
public class Test03 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
System.out.println("++++++++++++++++++获取public修饰的对象++++++++++++++++++=");
Class<?> aClass =Class.forName("com.qy143.demo03.Student");
Field nameField = aClass.getField("name");// 获取指定的name属性对象
System.out.println(nameField);
Field sexfield = aClass.getField("sex");
System.out.println(sexfield);
System.out.println("+++++++++++++++++++获取本类中指定的属性对象+++++++++++++++++++++++++++++");
Field namefield2 = aClass.getDeclaredField("name");// 获取本类中的属性对象
System.out.println(namefield2);
Field ageield2 = aClass.getDeclaredField("age");// 获取本类中的属性对象
System.out.println(ageield2);
// Field sexfield2 = aClass.getDeclaredField("sex");// 获取本类中的属性对象
// System.out.println(sexfield2);
System.out.println("+++++++++++++++++++获取全部public修饰的属性对象++++++++++++++++++++++++");
Field[] fields =aClass.getFields();
for (Field f:fields){
System.out.println(f);
}
System.out.println("++++++++++++++++++++++++++获取本类中所有属性对象");
Field[] declaredFields =aClass.getDeclaredFields();
for (Field f:declaredFields){
System.out.println(f);
}
}
}
class Father{
public String sex;
}
class Student extends Father{
public String name;
private int age;
public void show(){
System.out.println("++++++++++++++++++++show+++++++++++++++++++++");
}
public Student() {
}
Field类中操作有哪些
get(Object obj); 返回该所表示的字段的值 Field ,指定的对象上
set(Object obj,Object value); :为执行属性赋值
serAccessible(boolean) : 设置属性的可见性
例子:
package com.qy143.demo04;
import java.lang.reflect.Field;
public class Test04 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
Class<?> aClass = Class.forName("com.qy143.demo04.Student");
Object o =aClass.newInstance();
Field namefield = aClass.getField("name");
System.out.println(namefield.get(o)); // 获取name属性值
namefield.set(o,"张三"); // 为name属性对象赋值
System.out.println(namefield.get(o));
Field agefield = aClass.getDeclaredField("age");
agefield.setAccessible(true); // 设置私有属性的可见性 , 不建议使用因为其打破了面向对象的封装性
agefield.set(o,15); // 报错了 因为私有的无法访问
System.out.println(o);
}
}
class Father{
public String sex;
}
class Student extends Father {
public String name;
private int age;
public void show(){
System.out.println("++++++++++++++++++++show+++++++++++++++++++++");
}
public Student() {
}
5.如何获取方法类Method
Method getDeclaredMethod(String name, Class<?>... parameterTypes) : 获取当前类中指定的方法名 (不包括父类)
Method getDeclaredMethods() : 获取当前类中所有的方法 (不包括父类)
Method getMethod(String name, Class<?>... parameterTypes) : 获取指定类中的public修饰的方法 (包含父类)
Method getMethods() : 获取指定类全部public方法(包含父类)
例子:
package com.qy143.demo05;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test05 {
public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, NoSuchFieldException, InvocationTargetException {
Class<Student> studentClass = Student.class;
Student student = studentClass.newInstance();
Method show = studentClass.getMethod("show");
System.out.println(show);
System.out.println(show.getModifiers());// 获取修饰符 1 public 2 private..等等
Method print = studentClass.getMethod("print",int.class,String.class); // 可以调用父亲的方法并且加参数
System.out.println(print);
Method fun = studentClass.getDeclaredMethod("fun");
System.out.println(fun);
// 回调该方法
show.invoke(student);//Object o 对象名,Object... args 参数
fun.setAccessible(true);// 调用私有方法时需要设置可见性
fun.invoke(student);//Object o 对象名,Object... args 参数
Object o=print.invoke(student,15,"翻斗大街");
System.out.println(o);// 无返回值 为null
// 如果方法有返回值呢??
Method toString = studentClass.getMethod("toString");
Object invoke=toString.invoke(student);
System.out.println(invoke);
}
}
class Father{
public String sex;
public void print(int age,String addresss){
System.out.println("父类中的print方法"+age+" "+addresss);
}
}
class Student extends Father {
public String name;
private int age;
public void show(){
System.out.println("++++++++++++++++++++show方法+++++++++++++++++++++");
}
public Student() {
}
private void fun(){
