JavaSE复习总结之反射机制

news/2024/5/19 3:41:06 标签: Java, 反射, 后端

文章目录

  • 反射的概念
  • 反射的工作机制
  • 获取Class的三种方式
  • 获取到Class能干什么
    • 一、实例化对象
    • 二、获取类的属性
    • 三、访问对象属性
    • 四、获取类的方法
    • 五、调用对象方法
    • 六、通过反射机制调用构造方法实例化java对象
    • 七、获取父类和实现的接口
  • 资源绑定器

反射的概念

反射的概念是由 Smith 在 1982 年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力, 并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。

反射的工作机制

程序运行时,Java系统会一直对所有对象进行所谓的运行时类型识别,这项信息记录了每个对象所属的类。通过专门的类可以访问这些信息。用来保存这些信息的类是class 类,通过Java语言中的反射机制可以操作字节码文件

获取Class的三种方式

  • 第一种:Class c = Class.forName(“完整类名”);
  • 第二种:Class c = 对象.getClass();
  • 第三种:Class c = 任何类型.class;

获取到Class能干什么

一、实例化对象

	//不使用反射机制创建对象
	User user = new User();
	System.out.println(user);
	//使用反射机制创建对象
	try {
		// 通过反射机制,获取Class,通过Class来实例化对象
		Class c = Class.forName("com.bjpowernode.java.bean.User");
		// newInstance()调用的是无参构造,必须保证无参构造是存在的!
		Object obj = c.newInstance();
		System.out.println(obj);
	} catch (Exception e) {
		e.printStackTrace();
	}

二、获取类的属性

返回类型方法名描述
StringgetName()获取完整类名
StringgetSimpleName()获取简类名
Field[]getFields()获取类中所有的public修饰的属性
Field[]getDeclaredFields()获取类中所有的属性
FieldgetDeclaredField(String name)根据属性名获取属性

Filed类常用方法

返回类型方法名描述
StringgetName()获取属性名
intgetModifiers()返回的修饰符是一个数字(修饰符的代号)
ClassgetType()获取属性的类型
public class ReflectTest {
    public static void main(String[] args) throws Exception{
        Class studentClass = Class.forName("com.why.java.bean.Student");
        String className = studentClass.getName();
        System.out.println("完整类名:" + className);
        String simpleName = studentClass.getSimpleName();
        System.out.println("简类名:" + simpleName);
        // 获取类中所有的public修饰的Field
        Field[] fields = studentClass.getFields();
        System.out.println(fields.length);
        // 取出这个Field
        Field f = fields[0];
        // 取出这个Field它的名字
        String fieldName = f.getName();
        System.out.println(fieldName);
        // 获取所有的Field
        Field[] fs = studentClass.getDeclaredFields();
        // 遍历
        for(Field field : fs){
            // 获取属性的修饰符列表
            int i = field.getModifiers(); 
            // 将这个“代号”数字转换成“字符串”吗
            String modifierString = Modifier.toString(i);
            System.out.print(modifierString+" ");
            // 获取属性的类型
            Class fieldType = field.getType();
            String fName = fieldType.getSimpleName();
            System.out.print(fName+" ");
            // 获取属性的名字
            System.out.println(field.getName());
        }
    }
}

【运行结果】

完整类名:com.why.java.bean.Student
简类名:Student
private String name
protected int age
 boolean sex
public int no
public static final double MATH_PI

Process finished with exit code 0

三、访问对象属性

给属性赋值set
获取属性的值get

public class ReflectTest {
    public static void main(String[] args) throws Exception{

        // 不使用反射机制访问一个对象的属性
        Student s = new Student();
        s.no = 1111;
        System.out.println(s.no);

        // 使用反射机制访问一个对象的属性
        Class studentClass = Class.forName("com.why.java.bean.Student");
        Object obj = studentClass.newInstance(); 
        // 获取no属性(根据属性的名称来获取Field)
        Field noFiled = studentClass.getDeclaredField("no");
        // 给obj对象(Student对象)的no属性赋值
        noFiled.set(obj, 22222); // 给obj对象的no属性赋值2222
        // 读取属性的值
        System.out.println(noFiled.get(obj));
        Field nameField = studentClass.getDeclaredField("name");
        // 这样设置完之后,在外部也是可以访问private的。
        nameField.setAccessible(true);
        // 给name属性赋值
        nameField.set(obj, "jackson");
        // 获取name属性的值
        System.out.println(nameField.get(obj));
    }
}

四、获取类的方法

返回类型方法名描述
Method[]getDeclaredMethods()获取所有的方法包括私有
MethodgetMethod(String name, Class<?>… parameterTypes)根据方法名和形参获取方法
Class[]getParameterTypes()获取形参类型
Constructor[]getDeclaredConstructors()获取所有的构造方法
public class ReflectTest {
    public static void main(String[] args) throws Exception{
        Class userServiceClass = Class.forName("com.why.java.service.UserService");
        Method[] methods = userServiceClass.getDeclaredMethods();
        // 遍历Method
        for(Method method : methods){
            // 获取修饰符列表
            System.out.print(Modifier.toString(method.getModifiers())+" ");
            // 获取方法的返回值类型
            System.out.print(method.getReturnType().getSimpleName()+" ");
            // 获取方法名
            System.out.print(method.getName()+"(");
            // 方法的修饰符列表(一个方法的参数可能会有多个。)
            Class[] parameterTypes = method.getParameterTypes();
            for(Class parameterType : parameterTypes){
                System.out.print(parameterType.getSimpleName()+",");
            }
            System.out.println(")");
        }
    }
}

【运行结果】

public void login(int,)
public boolean login(String,String,)
public void logout()

Process finished with exit code 0

五、调用对象方法

public class ReflectTest10 {
    public static void main(String[] args) throws Exception{
        // 不使用反射机制调用方法
        UserService userService = new UserService();
        boolean loginSuccess = userService.login("admin","123");
        System.out.println(loginSuccess ? "登录成功" : "登录失败");

        // 使用反射机制来调用一个对象的方法
        Class userServiceClass = Class.forName("com.why.java.service.UserService");
        Object obj = userServiceClass.newInstance();
        // 获取Method
        Method loginMethod = userServiceClass.getDeclaredMethod("login", String.class, String.class);
        Object retValue = loginMethod.invoke(obj, "admin","123123");
        System.out.println(retValue);
    }
}

六、通过反射机制调用构造方法实例化java对象

public class ReflectTest12 {
    public static void main(String[] args) throws Exception{
        // 使用反射机制怎么创建对象
        Class c = Class.forName("com.bjpowernode.java.bean.Vip");
        // 调用无参数构造方法
        Object obj = c.newInstance();
        System.out.println(obj);
        // 调用有参数的构造方法
        // 第一步:先获取到这个有参数的构造方法
        Constructor con = c.getDeclaredConstructor(int.class, String.class, String.class,boolean.class);
        // 第二步:调用构造方法new对象
        Object newObj = con.newInstance(110, "jackson", "1990-10-11", true);
        System.out.println(newObj);

        // 获取无参数构造方法
        Constructor con2 = c.getDeclaredConstructor();
        Object newObj2 = con2.newInstance();
        System.out.println(newObj2);
    }
}

七、获取父类和实现的接口

返回类型方法名描述
ClassgetSuperclass()获取父类
Class[]getInterfaces()获取实现的所有接口
public class ReflectTest13 {
    public static void main(String[] args) throws Exception{
        Class stringClass = Class.forName("java.lang.String");
        // 获取String的父类
        Class superClass = stringClass.getSuperclass();
        System.out.println(superClass.getName());
        // 获取String类实现的所有接口
        Class[] interfaces = stringClass.getInterfaces();
        for(Class in : interfaces){
            System.out.println(in.getName());
        }
    }
}

【运行结果】

java.lang.Object
java.io.Serializable
java.lang.Comparable
java.lang.CharSequence
java.lang.constant.Constable
java.lang.constant.ConstantDesc

Process finished with exit code 0

资源绑定器

java.util包下提供了一个资源绑定器,便于获取属性配置文件中的内容。使用以下这种方式的时候,属性配置文件xxx.properties必须放到类路径下。

properties文件

className=java.lang.String
public class ResourceBundleTest {
    public static void main(String[] args) {

        // 这个文件必须在类路径下。文件扩展名也必须是properties
        // 并且在写路径的时候,路径后面的扩展名不能写
        //ResourceBundle bundle = ResourceBundle.getBundle("db");

        ResourceBundle bundle = ResourceBundle.getBundle("com/why/java/bean/db");
        String className = bundle.getString("className");
        System.out.println(className);
    }
}

【结果】

java.lang.String

Process finished with exit code 0

http://www.niftyadmin.cn/n/858188.html

相关文章

linux统计代码注释率,Linux可信计算机制模块详细分析之核心文件分析(8)tpm.c核心代码注释(中)...

原标题&#xff1a;Linux可信计算机制模块详细分析之核心文件分析(8)tpm.c核心代码注释(中)/*设置TPM命令格式*/ssize_t tpm_getcap(struct device *dev, __be32 subcap_id, cap_t *cap,const char *desc){struct tpm_cmd_t tpm_cmd;int rc;struct tpm_chip *chip dev_get_drv…

e480换高分屏_ThinkPadE480电脑(i5-8250u 8G内存 256G固态 高分屏0QCD 14英寸) 京东5699元...

ThinkPadE480是一款升级英特尔 酷睿i7 8代系列处理器的全新产品&#xff0c;轻薄纤巧的造型美入人心&#xff0c;这款产品最大的亮点就是它所搭载的Intel 酷睿i7 8550U 四核心/八线程处理器&#xff0c;拥有高达4GHz的最大睿频以及8MB三级缓存&#xff0c;理论性能强大到能够媲…

linux adsl实现原理,ADSL原理以及ADSL系统组成简介

ADSL(Asymmetric Digital Subscriber Line )的全称是非对称数字式用户线路&#xff0c;之所以称之为非对称&#xff0c;是由于其实现的速率是上行小于1Mbps&#xff0c;下行小于7Mbps。它是一种可以让家庭或小型企业利用现有电话网采用高频数字压缩方式&#xff0c;对网络服务商…

Linux系统安装Nginx指南

文章目录下载Nignx安装包安装前准备上传安装包上传到Linux解压开放防火墙端口启动Nignx服务关于403Forbidden下载Nignx安装包 Nginx官方网站 点击右侧download 选择想要下载的版本(我选择的是1.14.2) 安装前准备 1、gcc编译器是否安装 #检查是否安装&#xff1a; yum li…

oauth最后的确认按钮_OAuth2.0认证和授权机制讲解

第一章.OAuth2.0 介绍OAuth认证OAuth认证是为了做到第三方应用在未获取到用户敏感信息(如&#xff1a;账号密码、用户PIN等)的情况下&#xff0c;能让用户授权予他来访问开放平台(主要访问平台中的资源服务器Resource Server)中的资源接口。其流程主要是&#xff1a;* 1.用户首…

linux的常用基本命令cd,Linux常用基本命令( tree, pwd, cd )

pwd与cd命令>pwd命令是“print working directory”中每个单词的首字母缩写&#xff0c;其功能是显示当前工作目录的绝对路径。在实际工作中&#xff0c;我们在命令行操作命令时&#xff0c;经常会在各个目录路径之间进行切换&#xff0c;此时可使用pwd命令快速查看当前我们…

proxmox安装linux无法上网,Proxmox安装pfSense教程

该教程适用于较新的Proxmox版本。在教程开始之前&#xff0c;假设&#xff1a;Proxmox主机已启动并正在运行主机至少具有两个可用于WAN和LAN的网络接口。已经将pfSense光盘映像上传到主机一、Proxmox网络设置为了虚拟化pfSense软件&#xff0c;首先在Proxmox上创建两个Linux网桥…

Eureka——服务注册与发现

文章目录Eureka简介准备工作搭建Eureka注册中心服务注册服务发现测试Eureka简介 Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。 Eureka包含两个组件&#xff1a;Eureka Se…