【java】反射基础

news2025/1/12 15:47:16

Class类

import java.io.*;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException {
        Class<String> clazz = String.class;   //使用class关键字,通过类名获取
        Class<?> clazz2 = Class.forName("java.lang.String");
        //使用Class类静态方法forName(),通过包名.类名获取,注意返回值是Class<?>
        String c=new String("coleak");
        Class<?> clazz3 = c.getClass();  //通过实例对象获取
        System.out.println(clazz);
    }
}

class java.lang.String

Class类也是一个泛型类,只有第一种方法,能够直接获取到对应类型的Class对象,而以下两种方法使用了?通配符作为返回值,但是实际上都和第一个返回的是同一个对象

即:在JVM中每个类始终只存在一个Class对象,无论通过什么方法获取,都是一样的

public class Main {
    public static void main(String[] args) {
        Class<String[]> clazz = String[].class;
        System.out.println(clazz.getName());  //获取类名称(得到的是包名+类名的完整名称)
        System.out.println(clazz.getSimpleName());
        System.out.println(clazz.getTypeName());
        System.out.println(clazz.getClassLoader());   //获取它的类加载器
    }
}

Class对象与多态

import java.lang.reflect.Type;
public class Main {
    public static void main(String[] args) {
        String str = "";
        System.out.println(str.getClass());
        System.out.println(str instanceof String);
        System.out.println(str.getClass() == String.class);   //直接判断是否为这个类型
        Integer i = 10;
        System.out.println(i.getClass().asSubclass(Number.class));   //当Integer不是Number的子类时,会产生异常
        System.out.println(i.getClass().getSuperclass());
        Type type = i.getClass().getGenericSuperclass();
        //getGenericSuperclass()获取父类的原始类型
        System.out.println(type);
        System.out.println(type instanceof Class);
    }
    }

class java.lang.String
true
true
class java.lang.Integer
class java.lang.Number
class java.lang.Number
true

创建类对象

无参构造

public class Main {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException
    {
        Class<Student> clazz = Student.class;
        Student student = clazz.newInstance();
        student.test();
    }

    static class Student{
        public void test(){
            System.out.println("coleak");
        }
    }
    }

构造器

import java.lang.reflect.InvocationTargetException;
public class Main {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class<Student> clazz = Student.class;
        Student student = clazz.getConstructor(String.class).newInstance("coleak");
        student.test();
    }
    static class Student{

        public Student(String str){}

        public void test(){
            System.out.println("cc");
        }
    }
    }

非public权限

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Main {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class<Student> clazz = Student.class;
        Constructor<Student> constructor = clazz.getDeclaredConstructor(String.class);
        constructor.setAccessible(true);   //修改访问权限
        Student student = constructor.newInstance("coleak");
        student.test();
    }
    static class Student{
        private final String name;
        private Student(String str){
            this.name=str;
        }
        public void test(){
            System.out.println(name);
        }
    }
    }

调用类方法

public权限

import java.lang.reflect.Method;
public class Main {
    public static void main(String[] args) throws ReflectiveOperationException {
        Class<?> clazz = Class.forName("com.test.Student");
        Object instance = clazz.newInstance();   //创建出学生对象
        Method method = clazz.getMethod("test", String.class);   
        //通过方法名和形参类型获取类中的方法
        method.invoke(instance, "coleak");   
        //通过Method对象的invoke方法来调用方法
    }
    }

非public权限

package com.test;
public class Student {
    private void test(String str){
        System.out.println("coleak"+str);
    }
}

import java.lang.reflect.Method;
public class Main {
    public static void main(String[] args) throws ReflectiveOperationException {
        Class<?> clazz = Class.forName("com.test.Student");
        Object instance = clazz.newInstance();   //创建出学生对象
        Method method = clazz.getDeclaredMethod("test", String.class);   
        //通过方法名和形参类型获取类中的方法
        method.setAccessible(true);
        method.invoke(instance, "coleak");   //通过Method对象的invoke方法来调用方法
    }
    }

import java.lang.reflect.Method;
public class Main {
    public static void main(String[] args) throws ReflectiveOperationException {
        Class<?> clazz = Class.forName("com.test.Student");
        Method method = clazz.getDeclaredMethod("test", String.class);   //通过方法名和形参类型获取类中的方法
        System.out.println(method.getName());   //获取方法名称
        System.out.println(method.getReturnType());   //获取返回值类型
    }
}

//方法的参数为可变参数时
Method method = clazz.getDeclaredMethod("test", String[].class);

可以直接通过Method对象来获取这些信息

修改类的属性

public权限

package com.test;
public class Student {
    public int i;
    public void test(){
        System.out.println("coleak"+i);
    }
}

import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Main {
    public static void main(String[] args) throws ReflectiveOperationException {
        Class<?> clazz = Class.forName("com.test.Student");
        Object instance = clazz.newInstance();
        Field field = clazz.getField("i");   //获取类的成员字段i
        field.set(instance, 100);   //将类实例instance的成员字段i设置为100
        Method method = clazz.getMethod("test");
        method.invoke(instance);
    }
}

非public权限

import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Main {
    public static void main(String[] args) throws ReflectiveOperationException {
        Class<?> clazz = Class.forName("com.test.Student");
        Object instance = clazz.newInstance();
        Field field = clazz.getDeclaredField("i");   //获取类的成员字段i
        field.setAccessible(true);
        field.set(instance, 100);   //将类实例instance的成员字段i设置为100
        Method method = clazz.getMethod("test");
        method.invoke(instance);
    }
}

类加载器

在这里插入图片描述

public class Main {
    public static void main(String[] args) {
        System.out.println(Main.class.getClassLoader());   //查看当前类的类加载器
        System.out.println(Main.class.getClassLoader().getParent());  //父加载器
        System.out.println(Main.class.getClassLoader().getParent().getParent());  //爷爷加载器
        System.out.println(String.class.getClassLoader());   //String类的加载器
    }
}

jdk.internal.loader.ClassLoaders A p p C l a s s L o a d e r @ 2437 c 6 d c j d k . i n t e r n a l . l o a d e r . C l a s s L o a d e r s AppClassLoader@2437c6dc jdk.internal.loader.ClassLoaders AppClassLoader@2437c6dcjdk.internal.loader.ClassLoadersPlatformClassLoader@49e4cb85
null
null
BootstarpClassLoader是C++编写的,我们在Java中是获取不到的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/436141.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot源码学习系列——运行流程分析

前文SpringBoot源码学习系列——构造流程分析对SpringApplication的实例化流程进行了介绍&#xff0c;完成了基本配置文件的加载及初始化&#xff0c;本文对其run方法进行介绍&#xff0c;看看Spring Boot是如何启动运行的。 run方法核心流程 可以看到&#xff0c;SpringAppli…

主机串口—虚拟机串口—linux系统串口之间的关系(实现主机和虚拟机之间的串口通信)

目录 1、准备工具 2、实现机理 3、实现过程 4、虚拟机串口 —— Linux系统串口文件 1、准备工具 VSPD&#xff1a;作用是在主机上创建虚拟串口 VSPD 下载&#xff1a;VSDP 汉化版下载VSPD 配置教程&#xff1a;VSPD虚拟串口工具实用工具–小白入门篇 | 码农家园 串口调…

MES功能设计规格书

软件功能结构 项目实施方案 概述 按总体规划&#xff0c;MES项目分三个阶段实施&#xff0c;第一阶段先在终端电器制造部和控制电器制造部进行试点实施。 第一阶段目标 建立基本的MES系统框架&#xff0c;提供工厂建模等基础功能。将目前的Excel生产排程纳入到系统管理&…

wps宏编辑器API关于msgbox和inputbox的使用说明

WPS宏编辑器API参考关于函数列举了3个&#xff1a;DoEvents、InputBox和MsgBox&#xff0c;其中DoEvents有点不好理解&#xff0c;应该在什么场景下使用也缺乏官网指导说明&#xff0c;因此本文重点讲述InputBox和MsgBox的使用说明。 1、DoEvents 处理进程的消息队列中的消息…

AI菜鸡浅谈ChatGpt

最近最火的话题可能就是Chatgpt &#xff0c;这个对话机器人横空出世&#xff0c;大大突破了人类之前对AI 对话机器人的认知和预期&#xff0c;上次这样的颠覆认知的突破还是7年前的阿法狗&#xff0c;但是这一次Chatgpt 带来的革命可能要更深远。我从以下几个方面来谈一下我对…

Centos7.6集群部署海豚调度3.1.5

目录 前置准备工作&#xff08;所有机器&#xff09;主机规划数据库规划用户规划目录规划配置/etc/hostsjdk安装进程树分析配置ssh免密部署zookeeper启动zookeeper下载DolphinScheduler 二进制包修改install_env.sh配置修改dolphinscheduler_env.sh配置文件 安装&#xff08;ty…

virtualbox 安装centos

在virtualbox安装centos时&#xff0c;遇到了一些问题&#xff0c;此处记录下&#xff0c;希望可以帮助一些小伙伴。 一、下载centos 进入官网下载地址&#xff1a;Download (centos.org) 然后选择阿里云镜像地址&#xff1a;centos-7.9.2009-isos-x86_64安装包下载_开源镜像…

TensorFlow版本与其他库的版本之间问题

使用TensorFlow的版本不一样&#xff0c;对应的库的版本也需不一样&#xff0c;这个有许多需要注意的地方。 比如Keras库&#xff0c; 当我使用tensorflow2.1.0版本时&#xff0c;安装Keras2.10.0这个库会导致运行报错&#xff0c; 那么就需要降低其版本到与之匹配&#xff…

AQS 和CAS详解

&#x1f3c6;今日学习目标&#xff1a; &#x1f340;JDBC事务 Hibernate事务 EJB事务详解 ✅创作者&#xff1a;林在闪闪发光 ⏰预计时间&#xff1a;30分钟 &#x1f389;个人主页&#xff1a;林在闪闪发光的个人主页 &#x1f341;林在闪闪发光的个人社区&#xff0c;欢迎你…

初识Linux篇

初识Linux篇 Linux环境的搭建1.什么是Linux2.Linux环境的安装云服务器Linux安装 总结 Linux环境的搭建 &#x1f60a;首先&#xff0c;在学习Linux之前&#xff0c;先了解一下Linux&#x1f60a; 1.什么是Linux Linux是一种操作系统软件&#xff0c;就像手机中的安卓&#xff…

Vue中的导航守卫

router官网-导航守卫 导航守卫常用的主要有三种&#xff1a;全局前置守卫(beforeEach)、路由独享守卫(beforeEnter)、组件内守卫(beforeRouteEnter) 路由独享守卫 在路由配置上直接定义 beforeEnter 守卫 <body> <div id"app"><h1>欢迎使用路由&l…

在没有魔法的情况下,如果让ChatGPT帮我们写代码

ChatGPT写代码 ✋ChatGPT 是一个基于人工智能的自然语言处理模型&#xff0c;可以帮助程序员更高效地、更自然地与计算机交互。ChatGPT 可以解决程序员在日常开发中遇到的各种问题&#xff0c;例如语法错误、API 使用、代码实现、架构设计等等。 &#x1f4a5;通过与 ChatGPT…

操作系统1(什么是操作系统、程序和编译器)

1.什么是操作系统&#xff1f; 1.什么是操作系统&#xff1f; 对单一计算机硬件系统做出抽象、支撑程序执行的软件系统。通过“虚拟化”硬件资源为程序运行提供服务的软件。 操作系统可以访问任何硬件资源。 2.什么是程序&#xff1f; 程序就是一个状态机。 程序计算sysc…

面了十几家公司测试岗,我终于悟了,面试无非就是这些题

测试岗的面试其实都是大同小异的&#xff0c;这里我收集整理了185道高频面试题&#xff0c;希望对在找工作或者准备跳槽的各位小伙伴有所帮助&#xff01; 一. 测试基础 1.如何制定测试计划 参考答案&#xff1a; 测试计划包括测试目标、测试范围、测试环境的说明、测试类型…

SpringBoot 实现多个子域共享 cookie

SpringBoot 实现多个子域共享 cookie 项目信息cookie 共享需求如何实现 环境配置配置域SpringBoot 配置 https 访问 后端代码验证验证后端解析 cookie 项目信息 使用SpringBoot web框架&#xff0c;版本号 2.7.10 <dependency><groupId>org.springframework.boot&…

Ambari 操作HDP组件迁移

目录 ​ 一、集群信息 1.1 HDP版本信息 1.2 服务器信息 二、服务迁移操作 一、集群信息 1.1 HDP版本信息 1.2 服务器信息 角色 IP 组件 hdp103 192.168.2.152 NameNode hdp104 192.168.2.153 新 NameNode hdp105 192.168.2.154 旧NameNode 二、服务迁移操作 我…

6、苹果签名原理

一、iOS应用签名原理 代码签名双层代码签名描述文件 1.1 代码签名 代码签名是对可执行文件或脚本进行数字签名,用来确认软件在签名后未被修改或损坏的措施. 和数字签名原理一样,只不过签名的数据是代码. 1.1.1 简单的代码签名 - 在iOS出来之前,以前的主流操作系统(Mac/Win…

自动控制原理模拟卷5

自动控制原理模拟题五 Question1 液位自动控制系统原理示意图如下图所示,在任意情况下,希望液面高度 c c c维持不变,说明系统工作原理并画出系统方块图。 解: 当电位器电刷位于中点位置时,电动机不动,控制阀门有一定的开度,使水箱中流入水量与流出水量相等,从而液面保…

C6678-缓存和内存

C6678-缓存和内存 全局内存映射扩展内存控制器&#xff08;XMC&#xff09;-MPAX内存保护与地址扩展使用例程缓存 全局内存映射 扩展内存控制器&#xff08;XMC&#xff09;-MPAX内存保护与地址扩展 每个C66x核心都具有相同大小的L1和L2缓存&#xff0c;并且可配置为普通内存使…

【微信小程序-原生开发】实用教程21 - 分包

分包的流程 当微信小程序主包大小超过2M时&#xff0c;则需要对微信小程序进行分包&#xff0c;方法如下&#xff1a; 1. 转移页面文件 在项目根目录下&#xff0c;新建文件夹 package1 &#xff08;即自定义的分包名为 package1 &#xff09;文件夹 package1 内新建文件夹 p…