Java_反射相关类

一、反射的概念

        在运行时,对任意一个类都可以获取其属性  方法构造等(类结构);对任意对象都能对属性进行赋值,对方法进行执行,可以操作类。这种动态获取类信息以及动态对类进行操作的机制称之为反射机制(reflect)

、反射相关类

类名

用途

Class类

代表类的实体,在运行的Java应用程序中表示类和接口

Field类

代表类的成员变量(成员变量也称为类的属性)

Method类

代表类的方法

Constructor类

代表类的构造方法

Annotation类

代表注解

 2.1 Class类


        
Class代表类的实体,在运行的Java应用程序中表示类和接口。在这个类中提供了很多有用的方法,这里对他们简单的分类介绍。

2.1.1 获得Class相关的方法

1)Class.forName();

Class clazz1=Class.forName("com.aaa.getclass.Person");

对象.getClass();

2)Person p= new Person();

p.getClass()

3)类名.class;

Class clazz2=Person.class;

通过反射实例化:

Class对象.newInstance()

通过 Constructor 对象的 newInstance() 方法

创建一个人类与学生类进行演示

package com.aaa.reflectDemo.reflect;

import com.aaa.reflectDemo.ann.MyAnn;

import java.io.Serializable;

/**
 * @author :caicai
 * @date :Created in 2022/6/14 8:56
 * @description:Person类
 * @modified By:
 * @version:
 */
@MyAnn(name = "xxx")
public class Person implements Serializable {
    @MyAnn
    private int id;
    public String name;

    public Person() {
    }
    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    private double jiSuan(int a,int b,String fuhao){
        double c=0.0;
        switch (fuhao){
            case "+":
                c = a+b;
                break;
            case "-":
                c = a-b;
                break;
            case "*":
                c = a*b;
                break;
            case "/":
                c = a*1.0/b;
                break;
            default:
                System.out.println("不支持该方法");
        }
        return c;
    }

    public void introduce(String name){
        System.out.println("大家好我叫:"+name);
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
package com.aaa.reflectDemo.reflect;

/**
 * @author :caicai
 * @date :Created in 2022/6/14 8:57
 * @description:学生类
 * @modified By:
 * @version:
 */
public class Student extends Person{
    private int stuId;

    public Student() {
    }

    public Student(int stuId) {
        this.stuId = stuId;
    }

    public Student(int id, String name, int stuId) {
        super(id, name);
        this.stuId = stuId;
    }


    public int getStuId() {
        return stuId;
    }

    public void setStuId(int stuId) {
        this.stuId = stuId;
    }

    public void testDemo(){
        System.out.println("hahah");
    }
}

获得Class相关的方法相关代码演示

package com.aaa.reflectDemo.reflect;

/**
 * @author :caicai
 * @date :Created in 2022/8/15 16:25
 * @description:
 * @modified By:
 * @version:
 */
public class Test {
    public static void main(String[] args) {
        // 获得Class相关的方法
        // 1、通过类名(全路径名)获取class对象com.aaa.refelctDemo.reflect.Student
        try {
            Class<?> aClass = Class.forName("com.aaa.reflectDemo.reflect.Student");
            System.out.println(aClass);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //2、通过对象的getClass方法获取
        Person student = new Student();
        // 泛型上限  小于等于person
        Class<? extends Person> aClass = student.getClass();
        System.out.println(aClass);
        //3、通过.class的方式获取class对象
        Class<Student> aClass1 = Student.class;
        System.out.println(aClass1);
    }
}

结果打印

 2.1.2 获取类的基本信息的方法

getName()

获得类的完整路径名字

newInstance()

创建类的实例

getPackage()

获得类的包

getSimpleName()

获得类的名字

getSuperclass()

获得当前类继承的父类的名字

getAnnotation()

获取类上的注解

getInterfaces()

获得当前类实现的类或是接口

package com.aaa.reflectDemo.reflect;

import java.lang.annotation.Annotation;

public class Test {
    public static void main(String[] args) {
        // 获取类的基本信息的方法
        Class<Person> clazz = Person.class;
        System.out.println("==============获取类的基本信息·===============");
        String clazzName = clazz.getName();                  // 获得类的完整路径名字
        String packageName = clazz.getPackage().getName();   // 获得类的包
        String simpleName = clazz.getSimpleName();           // 获得类的名字
        System.out.println(clazzName);
        System.out.println(packageName);
        System.out.println(simpleName);
        // 通过反射实例化   Constructor 对象的 newInstance() 方法
        System.out.println("==============反射实例化=====================");
        try {
            Person person = clazz.newInstance();    //通过反射创建类的实例   调用的是无参的构造器
            person.setId(11);
            person.setName("反射实例化");
            System.out.println(person.toString());
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        // 泛型下限,大于等于person
        System.out.println("===========获得当前类继承的父类的名字===============");
        Class<? super Person> superclass = clazz.getSuperclass();   // 获得当前类继承的父类的名字
        System.out.println(superclass);
        //获取注解
        System.out.println("===========获获取类上的注解=======================");
        Annotation[] annotations = clazz.getAnnotations();//  获取类上的注解
        System.out.println(annotations.length);
        for (Annotation annotation : annotations) {
            System.out.println(annotation.toString());
        }
        //获取接口
        System.out.println("===========获得当前类实现的类或是接口===============");
        Class<?>[] interfaces = clazz.getInterfaces();   //获得当前类实现的类或是接口
        System.out.println(interfaces.length);
        for (Class<?> anInterface : interfaces) {
            System.out.println(anInterface.toString());
        }
    }
}

结果打印:

 2.2 Field类

2.2.1 获得类中属性相关的方法

方法

用途

getField(String name)

获得某个公有的属性对象

getFields()

获得所有公有的属性对象

getDeclaredField(String name)

获得某个私有属性对象

getDeclaredFields()

获得所有属性对象

 Field类中的方法

方法

用途

equals(Object obj)

属性与obj相等则返回true

get(Object obj)

获得obj中对应的属性值

set(Object obj, Object value)

设置obj中对应属性值

package com.aaa.reflectDemo.reflect;
import java.lang.reflect.Field;
public class Test {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        // Field类   获得类中属性相关的方法
        System.out.println("==========获得类中属性相关的方法=============");
        Class<Person> clazz = Person.class;
        // 获取公有属性
        Field field = clazz.getField("name");
        System.out.println(field);
        Field[] fields = clazz.getFields();
        for (Field field1 : fields) {
            System.out.println(field1);
        }
        //获取私有属性(可以获取共有的和私有的)
        System.out.println("-------------------私有属性-----------------");
        Field id = clazz.getDeclaredField("id");
        System.out.println(id);
        Field[] fields1 = clazz.getDeclaredFields();
        for (Field field1 : fields1) {
            System.out.println(field1);
        }
        // Field类中的方法 获得person中对应的属性值
        System.out.println("----------公有/私有属性取值赋值------------");
        Person person = new Person(1,"张三");
        Field name = clazz.getField("name");
        Field ids = clazz.getDeclaredField("id");
        ids.setAccessible(true);                         // 私有取值时先放行
        System.out.println("姓名:"+name+"\t 用户id:"+ids);
        // 取值
        System.out.println("姓名:"+name.get(person)+"\t id为:"+ids.get(person));
        System.out.println("反射赋值在以前"+person.toString());
        System.out.println("----------------赋值---------------------");
        name.set(person,"李四");    // 共有属性
        id.setAccessible(true);    // 私有属性 需要现先予临时赋权限 才可以修改值
        id.set(person,2);
        System.out.println("反射赋值之后"+person.toString());
    }
}

结果打印

2.3 Method类

2.3.1 CLASS获得类中方法相关的方法

方法

用途

getMethod(String name, Class...<?> parameterTypes)

根据方法名和参数类型获取方法对象

getMethods()

获得该类所有公有的方法,不包含构造方法

getDeclaredMethod(String name, Class...<?> parameterTypes)

获得该类某个方法

getDeclaredMethods()

获得该类所有方法,不包含父类

package com.aaa.reflectDemo.reflect;
import java.lang.reflect.Method;

public class Test1 {
    public static void main(String[] args) throws NoSuchMethodException {
        // Method类   CLASS获得类中方法相关的方法
        // getMethod(String name, Class...<?> parameterTypes) 根据方法名和参数类型获取方法对象
        System.out.println("==============获取类中的方法=================");
        Class<Person> clazz = Person.class;
        System.out.println("------------获取单一方法----------");
        //获取单的某个方法
        Method introduce2 = clazz.getMethod("introduce", String.class);
        System.out.println(introduce2.toString());
        System.out.println("-----------------获取公有方法--------------------");
        // 获取所有公有方法 包含继承的 不包含有参无参构造方法
        Method[] methods = clazz.getMethods();
        System.out.println(methods.length);
        for (Method method : methods) {
            System.out.println(method.toString());
        }
        System.out.println("-----------------获取私有方法--------------------");
        //获取所有的私有方法包含公有的,不包含继承的
        Method[] methods2 = clazz.getDeclaredMethods();
        System.out.println(methods2.length);
        for (Method method : methods2) {
            System.out.println(method.toString());
        }
    }
}

结果打印:

2.4 Constructor类

获得类中构造器相关的方法

方法

用途

getConstructor(Class...<?> parameterTypes)

获得该类中与参数类型匹配的公有构造方法

getConstructors()

获得该类的所有公有构造方法

getDeclaredConstructor(Class...<?> parameterTypes)

获得该类中与参数类型匹配的构造方法

getDeclaredConstructors()

获得该类所有构造方法

package com.aaa.reflectDemo.reflect;
import java.lang.reflect.Constructor;

public class Test {
    public static void main(String[] args) throws NoSuchMethodException {
        // Constructor类
        //获取单个参数的构造器
        Class<Person> clazz = Person.class;
        Constructor<Person> constructor = clazz.getConstructor();
//        Constructor<Person> constructor = clazz.getConstructor(int.class,String.class);
        System.out.println(constructor.toString());
    }
}

结果打印

2.5 Annotation类

创建一个自己的注解

package com.aaa.reflectDemo.ann;

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

/**
 * 我的注解
 * 元(meta)注解@Retention 指定注解生效的生命周期
 * 元注解@Target  指定注解标注的位置,
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD})
public @interface MyAnn {
    String name() default "";
}

 在java类上加上自定义注解,使用反射获取该注解

 

package com.aaa.reflectDemo.reflect;
import com.aaa.reflectDemo.ann.MyAnn;
public class Test1 {
    public static void main(String[] args) throws NoSuchMethodException {
        // Annotation类   使用反射获取该注解
        //获取单个注解
        Class<Person> clazz = Person.class;
        MyAnn annotation = clazz.getAnnotation(MyAnn.class);
        System.out.println(annotation);
        //获取注解中的值   如果使用反射获取注解信息,注解必须@Retention(RetentionPolicy.RUNTIME)
        System.out.println(annotation.name());
    }
}

结果打印

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜鸡本蔡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值