java反射

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}
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值