java反射

1. 回顾

  1. 泛型: [泛型类,泛型接口,泛型方法]

    public class 类名<泛型标志...>{

    ​ //使用泛型标志定义数据类型

    }

    public interface 接口<泛型标志>{

    ​ //使用泛型标志定义抽象方法

    }

    public class 类名 implements 接口<泛型类型>{

    }

    public class 类名<泛型标志> implements 接口<泛型标志>{

    ​ //注意:类的泛型标志要和接口的泛型标志一致

    }

    修饰符 <泛型标志> 返回类型 方法名(泛型标志 参数名){

    }

  2. 泛型通配符 ?

  3. 泛型的上限 ? extends 类名

  4. 泛型的下限 ? super 类名

  5. 注解: 自定义注解

@Target(value="限制该注解可以使用在哪些位置。TYPE  METHOD Field PARAMTER")
@Retention(value="何时生效 SOURCE CLASS RUNTIME")
@Document(是否在生成api文档是显示该注解)
public  @interface 注解名{
    //注解中属性: 数据类型: 基本类型。字符串类型 以及上面类型的数组
    数据类型  属性名() [default 默认值]

}

使用注解: @注解名(只为value那么可以省略value 赋值的数组只有一个元素,省略{})

2. 正文

1. 什么反射?
2. 如何获取反射类对象.
3. 如何根据反射类获取类对象
4. 如何获取类中属性对象
5. 如何获取类中方法对象
6. 如何获取类中构造方法对象

3.什么是反射?

  1. 反射它是框架设计的灵魂。什么是框架: 框架就是把重复的代码分离出来形成一个框架,它是一个别人设计好的一个半成品,在使用时只要填入自己的业务代码。好处: 提高开发效率。
  2. 反射: 在运行时,它是把类中成员抽取为其他类对象的过程。

1691649503939

4. 获取反射Class

从上面的分析我们知道,任意一个字节码都会通过ClassLoader类加载器,加载到JVM内存中,并以Class类对象的形式存在。注意:一个类的字节码只会被加载一次。 获取Class类对象的方式有三种:

第一种: Class.forName("类路径")

第二种: 类名.class

第三中: 对象.getClass();

package com.aaa.javabast2;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.lang.reflect.Field;

public class a {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //1
        Class<?> aClass1 = Class.forName("com.aaa.javabast2.b");
        System.out.println(aClass1);
        //2
        b b = new b();
        Class<? extends com.aaa.javabast2.b> aClass = b.getClass();
        System.out.println(aClass);
        //3
        Class<com.aaa.javabast2.b> bClass = b.class;
        System.out.println(bClass);
    }
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class b{
private String name;
private Integer age;
}

5. 通过反射类获取类对象

通过反射类Class类对象,调用newInstance()

package com.aaa.javabast2;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.lang.reflect.Field;

public class a {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {

        Class<com.aaa.javabast2.b> bClass = b.class;
        System.out.println(bClass);

        //创建对象
        com.aaa.javabast2.b b1 = bClass.newInstance();
        System.out.println(b1);
        System.out.println("++++++++++++++");


    }
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class b{
private String name;
private Integer age;
}

spring---spring.xml====>

--spring根据你传递的类路径----得到该类的反射类---并通过newInstance()创建类对象。

mybatis--=====> sqlSession.getMapper(UserDao.class);---->UserDao.class反射类---->mybatis创建UserDao接口的类对象。


6. 获取反射类中的属性成员对象

字节码中的属性成员被加载到内存中后会以Field类对象的形式存在。如何获取Field属性对象。

Class.getFields()
Class.getField(String)
Class.getDeclaredFields() 
Class.getDeclaredField(String) 
package com.aaa.javabast2;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.lang.reflect.Field;

public class a {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        
        Class<com.aaa.javabast2.b> bClass = b.class;
        System.out.println(bClass);
        //创建对象
        com.aaa.javabast2.b b1 = bClass.newInstance();
        //获取本类中的所有属性
        Field[] declaredFields = bClass.getDeclaredFields();
        for (Field field:declaredFields){
            System.out.println(field);
        }

  
        Class<com.aaa.javabast2.b> bClass1 = b.class;
        com.aaa.javabast2.b b2 = bClass1.newInstance();
        //得到反射类中的age属性对象
        Field age = bClass1.getDeclaredField("age");
        //通过set属性为b对象赋值
        age.set(b2,15);
        System.out.println(b2);
    }
}
class c{
    public String address;
    private String phone;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class b extends c{
private String name;
private Integer age;
}

6.2 Field类中具有的常用方法。

setAccessible(true): 设置允许访问私有属性
getAnnotation(注解.class):获取属性上的注解对象
package com.aaa.javabast2;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;

public class d {
    public static void main(String[] args) throws Exception {
        //1.获取反射类对象
        Class<Teacher> teacherClass = Teacher.class;
        //2.通过反射类得到类对象
        Teacher teacher = teacherClass.newInstance();
        //3. 得到反射类中的age属性对象
        Field ageField = teacherClass.getDeclaredField("age");
        //通过Age属性对象为teacher对象赋值  teacher.age=15
        ageField.set(teacher,15);

        Field nameField = teacherClass.getDeclaredField("name");
        //允许访问私有属性
        nameField.setAccessible(true);
        nameField.set(teacher,"刘德华");
        System.out.println(teacher);

        My annotation = nameField.getAnnotation(My.class);
        System.out.println(annotation.value());
    }
}
@Target(value = ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface My{
    String value();
}
class Teacher {
    @My(value = "姓名")
    private String name;
    public Integer age;

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

7. 获取方法类对象

获取对象的方法

Class.getMethods()
Class.getMethod(String, Class[])
Class.getDeclaredMethods()
Class.getDeclaredMethod(String, Class[]) 
package com.aaa.javabast2;

import java.lang.reflect.Method;

public class e {
    public static void main(String[] args) throws Exception {
        Class<Hello> helloClass = Hello.class;
        Hello hello = helloClass.newInstance();

        //获取本类中所有的Method方法对象
        Method[] declaredMethods = helloClass.getDeclaredMethods();
        for(Method m:declaredMethods){
            System.out.println(m);
        }

        //得到本类以及父类中public修饰的方法对象
        Method[] methods = helloClass.getMethods();
        for(Method m:methods){
            System.out.println(m);
        }
        
        //获取方法名为fun01的方法对象
        Method fun01 = helloClass.getMethod("fun01",int.class);
        System.out.println(fun01);

    }
}
class Hello{
    public String fun01(){
        System.out.println("~~~~~~~~~~~~~~~~~01");
        return "hello01";
    }
    public String fun01(int age){
        System.out.println("~~~~~~~~~~~~~~~~~01");
        return "hello01";
    }
    public String fun02(int age){
        System.out.println("~~~~~~~~~~~~~~02");
        return "hello01"+age;
    }
    private void fun03(){
        System.out.println("~~~~~~~~~~~~~~~03");
    }
}

7.2 Method类中常用的方法

invoke(): 执行该方法体。

getAnnotation()获取到方法上的的注释值

package com.aaa.javabast2;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

public class e {
    public static void main(String[] args) throws Exception {
        Class<Hello> helloClass = Hello.class;
        Hello hello = helloClass.newInstance();

        Method f = helloClass.getMethod("fun01",int.class,String.class);
        //回调该方法   执行该方法
        Object result = f.invoke(hello, 15,"fun01");
        System.out.println("====================="+result);
        //获取到f方法上的的注释值
        My02 annotation = f.getAnnotation(My02.class);
        System.out.println(annotation.value());
    }
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface My02{
    String value();
}
class Hello{
    public String fun01(){
        System.out.println("~~~~~~~~~~~~~~~~~01");
        return "hello01";
    }
    @My02("fun01")
    public String fun01(int age,String name){
        System.out.println("~~~~~~~~~~~~~~~~~01=========="+age+";============="+name);
        return "hello01";
    }

    public String fun02(int age){
        System.out.println("~~~~~~~~~~~~~~02");
        return "hello01"+age;
    }
    private void fun03(){
        System.out.println("~~~~~~~~~~~~~~~03");
    }
}

package com.aaa.javabast2;

import java.lang.reflect.Method;

public class e {
    public static void main(String[] args) throws Exception {
        Class<Hello> helloClass = Hello.class;
        Hello hello = helloClass.newInstance();

		//invokde属性执行方法
        Method fun03 = helloClass.getDeclaredMethod("fun03",String.class);
        fun03.setAccessible(true);
        Object invoke = fun03.invoke(hello,"a");
        System.out.println("+++++++++++++++++++++++++++"+invoke);

    }
}
class Hello{
    public String fun01(){
        System.out.println("~~~~~~~~~~~~~~~~~01");
        return "hello01";
    }
    public String fun01(int age){
        System.out.println("~~~~~~~~~~~~~~~~~01");
        return "hello01";
    }
    public String fun02(int age){
        System.out.println("~~~~~~~~~~~~~~02");
        return "hello01"+age;
    }
    private void fun03(String a){
        System.out.println("~~~~~~~~~~~~~~~03"+a);
    }
}

8. 获取构造对象

Class.getConstructors() 
Class.getConstructor(Class[]) 
Class.getDeclaredConstructors() 
package com.aaa.javabast2;
import java.lang.reflect.Constructor;


public class f {
    public static void main(String[] args) throws Exception {
        Class<?> aClass = Class.forName("com.aaa.javabast2.S");
        Object o = aClass.newInstance(); //得到类对象---调用构造函数
            //获取本类以及父类所有构造函数
        Constructor<?>[] a = aClass.getDeclaredConstructors();
            for (Constructor constructor:a){
                System.out.println(constructor);
            }

            //获取本类中所以public构造函数
        Constructor<?>[] b = aClass.getConstructors();
            for (Constructor c:b){
                System.out.println(c);
            }
    }
}
class g{
    public g(){
        System.out.println("父类的无参构造函数");
    }
    public g(String name){
        System.out.println("这是父类的有参构造函数:"+name);
    }
}
class S extends  g{
    public S(){
        super();
        System.out.println("子类的无参");
    }
    public S(String name){
        System.out.println("子类的有参:"+name);
    }
    private S(Integer age){
        System.out.println("有参私有构造");
    }
}

8.2 Constructor类中常用的方法

package com.aaa.javabast2;

import java.lang.reflect.Constructor;

public class h {
    public static void main(String[] args) throws Exception {
        Class<?> aClass = Class.forName("com.aaa.javabast2.i");

        //得到本类以及父类无参构造函数
        Constructor<?> declaredConstructor = aClass.getDeclaredConstructor();
        Object o = declaredConstructor.newInstance();
        //得到本类以及父类的有参构造函数
        Constructor<?> declaredConstructor2 = aClass.getDeclaredConstructor(String.class);
        Object aaa = declaredConstructor2.newInstance("aaa");
        System.out.println(aaa);
    }
}
class j{
    public j(){
        System.out.println("父类的无参构造函数");
    }
    public j(String name){
        System.out.println("这是父类的有参构造函数:"+name);
    }
}
class i extends  j{
    public i(){
        super();
        System.out.println("子类的无参");
    }
    public i(String name){
        System.out.println("子类的有参:"+name);
    }
    private i(Integer age){
        System.out.println("有参私有构造");
    }
}
posted @ 2023-08-11 09:14  知行合二为一  阅读(13)  评论(0编辑  收藏  举报