1.什么是反射
在运行时,对于任何一个类,它都能够知道这个类的所有属性和方法,对于任何一个对象,都能够调用它的任意一个方法和属性。
2.反射有什么用
反射是框架设计的灵魂。反射机制在很多框架中都有使用,比如spring、mybatis等等。可以获取类对象、动态调用方法、修改属性。
3.获取反射Class的三种方法
第一种:Class.forName("类路径")
第二种:类名.class
第三种:类实例.getClass()
public class Student {
private String name;
private int age;
}
public class TestFanShe {
public static void main(String[] args) throws Exception {
//第一种
Class<?> aClass1 = Class.forName("com.fanshe.demo01.test01.Student");
//第二种
Class<Student> aClass2 = Student.class;
//第三章
Class<? extends Student> aClass3 = new Student().getClass();
System.out.println(aClass1==aClass2);//true
System.out.println(aClass1==aClass3);//true
}
}
4.获取反射类实例化对象
Class类对象.newInstance()
添加有参构造器时,补一个无参构造器,newInstance()方法调用了无参构造方法,如果没有会抛出InstantiationException异常
Student student = aClass1.newInstance();
5.获取属性成员对象
Field getField(String name) 获取当前类以及父类某一个public的属性对象
Field[] getFields() 获取本类以及父类所有public的属性对象
Field getDeclaredField(String name) 获取本类某个属性对象
Field[] getDeclaredFields() 获取本类所有属性对象
class School{
public String address;
}
public class Student extends School{
private String name;
private int age;
}
public class TestFanShe {
public static void main(String[] args) throws Exception {
//第一种
Class<Student> aClass1 = (Class<Student>) Class.forName("com.fanshe.demo01.test01.Student");
//获取当前类name的成员对象
Field name = aClass1.getDeclaredField("name");
System.out.println(name);
//获取当前类所有的成员对象
Field[] fields = aClass1.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
}
//获取本类以及父类中某个public的成员对象
Field address = aClass1.getField("address");
System.out.println(address);
//获取本类以及父类中所有public的成员变量
Field[] fields1 = aClass1.getFields();
for (Field field : fields1) {
System.out.println(field);
}
}
}
5.1设置属性值
属性对象.set(类对象,属性值)
设置私有化属性需要开启允许访问私有属性的设置:setAccessible(true)
获取属性上的注解 :getAnnotation(注解.class)
//自定义My注解,有效时间运行时生效
@Retention(RetentionPolicy.RUNTIME)
@interface My{
String value();
}
class School{
public String address;
}
public class Student extends School{
@My("值")
private String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student() {
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class TestFanShe {
public static void main(String[] args) throws Exception {
//第一种
Class<Student> aClass1 = (Class<Student>) Class.forName("com.fanshe.demo01.test01.Student");
Student student = aClass1.newInstance();
//获取本类以及父类中某个public的成员对象
Field age = aClass1.getField("age");
age.set(student,20);
//获取当前类name的成员对象
Field name = aClass1.getDeclaredField("name");
//因为name是私有的,所以需要允许访问私有属性
name.setAccessible(true);
name.set(student,"张三");
System.out.println(student); //Student{name='张三', age=20}
My my = name.getAnnotation(My.class); //获取属性注解上的值
System.out.println(my.value()); //值
}
}
6.获取方法成员对象
Method getMethod(String name,参数类型...) 获取本类以及父类中某个public修饰的方法对象
Method[] getMethods() 获取本类以及父类中所有public修饰的方法对象
Method getDeclaredMethod(String name,参数类型...) 获取本类某个方法对象
Method[] getDeclaredMethods() 获取本类所有方法对象
package com.fanshe.demo01.test01;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@interface My{
String value();
}
class School{
public String address;
public void run1(){
System.out.println("父run1无参");
}
public void run1(String name){
System.out.println("父run1有参,name="+name);
}
}
public class Student extends School{
@My("值")
private String name;
public int age;
public void run1(){
System.out.println("子run1无参");
}
public void run1(String name){
System.out.println("子run1有参,name="+name);
}
@My("方法上的注解")
private void run2(){
System.out.println("子run2无参");
}
}
public static void main(String[] args) throws Exception {
//第一种
Class<Student> aClass1 = (Class<Student>) Class.forName("com.fanshe.demo01.test01.Student");
Student student = aClass1.newInstance();
//获取本类以及父类中某个public的方法对象
Method run1 = aClass1.getMethod("run1");//无参
Method run11 = aClass1.getMethod("run1", String.class);//有参
System.out.println(run1);//public void com.fanshe.demo01.test01.Student.run1()
System.out.println(run11);//public void com.fanshe.demo01.test01.Student.run1(java.lang.String)
//获取本类以及父类中所有public的方法对象
Method[] methods = aClass1.getMethods();
for (Method method : methods) {
System.out.println(method);
}
}
获取本类以及父类中所有public的方法对象发现多了9个是因为Object是所有类的父类
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
//获取本类中所有方法对象
Method[] declaredMethods = aClass1.getDeclaredMethods();
for (Method method : declaredMethods) {
System.out.println(method);
}
//获取本类中某个方法对象
Method run2 = aClass1.getDeclaredMethod("run2");
System.out.println(run2);
6.1执行该方法
方法.invoke(方法所在类对象,参数..)
获取方法上的注解 :getAnnotation(注解.class)
Class<Student> aClass1 = (Class<Student>) Class.forName("com.fanshe.demo01.test01.Student");
Student student = aClass1.newInstance();
//获取本类以及父类中某个public的方法对象
Method run1 = aClass1.getMethod("run1");//无参
Method run11 = aClass1.getMethod("run1", String.class);//有参
run1.invoke(student);//子run1无参
run11.invoke(student,"名字");//子run1有参,name=名字
Method run2 = aClass1.getDeclaredMethod("run2");
//允许访问私有方法
run2.setAccessible(true);
run2.invoke(student);//子run2无参
//获取方法上的注解
My my = run2.getAnnotation(My.class);
System.out.println(my.value());//方法上的注解
7.获取构造对象
Constructor getConstructor(参数类型...) 获取本类某个public的构造对象
Constructor[] getConstructors()获取本类所有public的构造对象
Constructor getDeclaredConstructor(参数类型...) 获取本类所有构造对象
Constructor[] getDeclaredConstructors() 获取本类所有构造对象
public class Student{
private String name;
public int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
public static void main(String[] args) throws Exception {
//第一种
Class<Student> aClass1 = (Class<Student>) Class.forName("com.fanshe.demo01.test01.Student");
Student student = aClass1.newInstance();
//获取本类中某个public的构造对象
Constructor<Student> constructor = aClass1.getConstructor(String.class,int.class);
System.out.println(constructor);
//获取本类中所有public的构造对象
Constructor<?>[] constructors = aClass1.getConstructors();
for (Constructor<?> constructor1 : constructors) {
System.out.println(constructor1);
}
//获取本类中某个构造对象
Constructor<Student> constructor1 = aClass1.getDeclaredConstructor();
System.out.println(constructor1);
//获取本类中所有构造对象\
Constructor<?>[] constructors1 = aClass1.getDeclaredConstructors();
for (Constructor<?> constructor2 : constructors1) {
System.out.println(constructor2);
}
}
7.1实例化构造方法
构造对象.newInsatance(参数...)
public class TestFanShe {
public static void main(String[] args) throws Exception {
//第一种
Class<Student> aClass1 = (Class<Student>) Class.forName("com.fanshe.demo01.test01.Student");
//获取本类中某个public的构造对象
Constructor<Student> constructor = aClass1.getConstructor(String.class,int.class);
Student student2 = constructor.newInstance("张三", 20);//有参构造方法
System.out.println(student2);//Student{name='张三', age=20}
//获取本类中某个构造对象
Constructor<Student> constructor1 = aClass1.getDeclaredConstructor();
Student student1 = constructor1.newInstance();//无参构造方法
System.out.println(student1);//Student{name='null', age=0}
}
}