首页 > 编程语言 >Java的反射

Java的反射

时间:2022-08-20 23:44:44浏览次数:55  
标签:反射 Java System User println import userClass out

在我们平时的开发中,我们肯定会遇到过spring框架。框架中我们几乎不需要手动去new对象。只需要通过一些简单的配置,spring就会把对象为我们创建好。这里就用到反射。下面我们详细的介绍一下Java中的反射。

什么是Java反射

Java的反射机制是指运行时获取类的状态属性,可以调用它的任意属性和方法。

反射的作用

  • 在运行时,构造任意一个类对象
  • 在运行时,判断一个类的完整结构,比如属性,方法,内部类,实现的接口
  • 在运行时,判断一个对象所属的类
  • 在运行时,调用任意对象的方法,获取属性
  • 在运行时,生成动态代理

关键的类

java.lang.Class: 类的对象,只有这个在lang包下

java.lang.reflect.Method: 方法的对象

java.lang.reflect.Field:属性的对象

java.lang.reflect.Constructor:构造函数的对象

反射对象的使用

  1. 首先这个是我们用来测试反射的pojo类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;

/**
 * @description:
 * @author: Administrator
 * @time: 2022/8/20
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private String name;
    private String hobby;
    private int age;

    public User(String name){
        this.name = name;
    }

    private @NotNull String sayHello(){
        return "Hello";
    }

    protected String sayProtected(){
        return "protect";
    }
}

  1. 测试Class
import com.hardy.pojo.User;
import org.junit.Test;

/**
 * @description:
 * @author: Administrator
 * @time: 2022/8/20
 */
public class TestClass {

    //        获取class的方式
    @Test
    public void testGetClass() throws ClassNotFoundException {
//        方式一:使用类的属性
        Class<User> userClass = User.class;
        System.out.println(userClass);

//        方式二:使用运行时类的getClass方法获取
        User user = new User();
        Class<? extends User> aClass = user.getClass();
        System.out.println(aClass);


//        方式三:使用Class的forName静态方法
        Class forName = Class.forName("com.hardy.pojo.User");
        System.out.println(forName);

//       方式四:使用classloader加载
        ClassLoader classLoader = User.class.getClassLoader();
        Class classLoad = classLoader.loadClass("com.hardy.pojo.User");
        System.out.println(classLoad);

    }
}
  1. 测试Construct
import com.hardy.pojo.User;
import org.junit.Test;

import java.lang.reflect.Constructor;

/**
 * @description:
 * @author: Administrator
 * @time: 2022/8/20
 */
public class TestConstructor {

    @Test
    public void test1() throws Exception {
        Class<User> userClass = User.class;
        Constructor<User> constructor = userClass.getConstructor();
        User hardy = constructor.newInstance();
        System.out.println(hardy);
        System.out.println("***********************");
//        通过参数的个数和类型来确定使用的构造参数
        Constructor<User> userConstructor = userClass.getConstructor(String.class);
        User user = userConstructor.newInstance("hardy");
        System.out.println(user);
    }
}
  1. 测试普通方法
package com.hardy;

import com.hardy.pojo.User;
import org.junit.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @description:
 * @author: Administrator
 * @time: 2022/8/20
 */
public class MethodTest {

    @Test
    public void test1() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
        Class<User> userClass = User.class;

        Constructor<User> constructor = userClass.getConstructor();
        User user = constructor.newInstance();
        // 获取所有public的方法, 不包含private/protected方法
        Method[] methods = userClass.getMethods();
        Arrays.stream(methods).forEach(System.out::println);
        System.out.println("*************************");
//        获取所有的方法,包括private/protect
        Method[] declaredMethods = userClass.getDeclaredMethods();
        Arrays.stream(declaredMethods).forEach(System.out::println);
        System.out.println("----------------------------");
        Method setName = userClass.getMethod("setName", String.class);
        setName.invoke(user, "myname");
        System.out.println(user);
        System.out.println("********************");
//        获取注解
        Method toString = userClass.getMethod("toString");
        Annotation[] annotations = toString.getAnnotations();
        Arrays.stream(annotations).forEach(System.out::println);

        String canonicalName = userClass.getCanonicalName();
        System.out.println(canonicalName);
//        调用私有方法
        Method sayHello = userClass.getDeclaredMethod("sayHello");
//        开启私有方法调用
        sayHello.setAccessible(true);
        sayHello.invoke(user);
    }
}
  1. 测试属性
package com.hardy;

import com.hardy.pojo.User;
import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;

/**
 * @description:
 * @author: Administrator
 * @time: 2022/8/20
 */
public class FieldTest {
    @Test
    public void test1() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        Class<User> userClass = User.class;
        Constructor<User> constructor = userClass.getConstructor();
        User user = constructor.newInstance();
        Field[] fields = userClass.getFields();
        Arrays.stream(fields).forEach(System.out::println);
        System.out.println("****************");
        Field[] declaredFields = userClass.getDeclaredFields();
        Arrays.stream(declaredFields).forEach(System.out::println);
        System.out.println("************");
        Field name = userClass.getDeclaredField("name");
        name.setAccessible(true);
//        获取属性的值
        Object o = name.get(user);
        System.out.println(o);
        System.out.println("-------------");
//       修改属性的值
        name.set(user, "Hardy");
        System.out.println(user);
    }
}

标签:反射,Java,System,User,println,import,userClass,out
From: https://www.cnblogs.com/hardyzhou/p/16609080.html

相关文章

  • 2022 Java 企业面试题汇总
    Java基础部分请列举至少三个JDK安装目录下的课程性程序(javac)请分析命题:“Java采用自动垃圾回收技术(GC),因此不会出现内存泄露”简单描述单子模式(单例模式)的各种不同实......
  • springMvc36-JavaEE-JSP基础-EL表达式和JSTL标签库(Taglibs)
    EL表达式和JSTL标签库:在JSP页面代替java代码,便于编写一.EL表达式   作用:${}简化脚本表达式<%=%>   j2ee1.4以前版本需指定<%@pageisELIgnored="false......
  • Java中的普通方法和构造方法的区别
    构造方法又称构造函数、构造器、constructor。//语法:[修饰列表]方法名(形参列表){方法体;}//显式无参构造方法publicclassUser{publicUser(){......
  • JavaSE——多线程
    多线程(⭐⭐⭐⭐⭐)实现多线程方式一:继承Thread类方法介绍方法名说明voidrun()在线程开启后,此方法将被调用执行voidstart()使此线程开始执行,Java虚拟机......
  • JavaScript使用reduce动态修改对象的属性名
      首先在添加到数组的时候,弄2个,把number冒号右边的是可以动态修改的,后面再使用reduce合并;    countryChildrenDouble的数据     合并之后twoO......
  • java学习笔记012 线程
    1.程序、进程、线程程序program是一段静态的可执行的指令进程process是正在运行的一个程序线程thread是进程内部的执行路径 每条线程具有独立的运行栈和程序计数器(PC)......
  • Java自定义注解
    ​/**作者:呆萌老师*☑csdn认证讲师*☑51cto高级讲师*☑腾讯课堂认证讲师*☑网易云课堂认证讲师*☑华为开发者学堂认证讲师*☑爱奇艺千人名师计划成员*在这里给大......
  • day23--Java集合06
    Java集合0613.Map接口0213.2Map接口常用方法put():添加remove():根据键键删除映射关系get():根据键获取值size():获取元素个数isEnpty():判断个数是否为0clear():清除containsKey():查......
  • Java跨线程传递数据方式总结
    在微服务调用链中,需要定义一个共享变量,在整个调用链中传递不跨线程的ThreadLocal线程变量,在当前线程任意地方都可共享(可理解为同一线程内部的全局变量)publicc......
  • 阿里巴巴Java开发手册 (黄山版)
    阿里巴巴Java开发手册(黄山版)1.变量命名1.1POJO类中的任何布尔类型的变量,都不要加is前缀,否则部分框架解析会引起序列化错误。说明:本文MySQL规约中的建表约定第......