java反射详解

动态代理

  • 什么是动态代理?

    特点:无侵入式的给代码增加额外的功能

    对象有什么方法想要被代理,代理就一定要有对应的方法

    对象和代理需要实现同一个接口,接口中就是被代理的方法

    调用者通过代理,调用代理中的方法,代理再去调用对象的方法

    //为对象生产代理对象的方法
    public static Object newProxyInstance(ClassLoader loader,Class<?>[] interface,InvocationHandler h){参数一:用于指定用哪个类加载器,去加载生成的代理类参数二:指定接口,这些接口用于指定生成的代理长什么样,也就是有哪些方法参数三:用来指定生成的代理对象要干什么事情
    }
    

    对象:

    package bean;public class BigStar implements Star {String name;//明星的名字@Overridepublic String toString() {return "BigStar{" +"name='" + name + '\'' +'}';}public String getName() {return name;}public void setName(String name) {this.name = name;}public BigStar() {}public BigStar(String name) {this.name = name;}@Overridepublic void sing(String name) {System.out.println(this.name + "在唱歌");}@Overridepublic void dance() {System.out.println(this.name + "在跳舞");}
    }

    接口:

    package bean;public interface Star {public abstract void sing(String name);//参数为歌名public void dance();
    }

    代理:

    package bean;import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;public class ProxyUtil {public static Star createProxy(BigStar bigStar){Star star = (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(), new Class[]{Star.class}, new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {/** 参数一:被代理的对象* 参数二:要运行的方法* 参数三:调用方法时,传递的实参** */if("sing".equals(method.getName())){System.out.println("准备场地,开始唱歌");}else if("dance".equals(method.getName())){System.out.println("准备场地,开始跳舞");}return method.invoke(bigStar,args);//调用对象的方法}});return star;}
    }

    测试:

    package bean;public class Test {public static void main(String[] args) {//获取代理对象BigStar bigStar = new BigStar("鸡哥");Star proxy = ProxyUtil.createProxy(bigStar);//调用方法proxy.sing("只因你太美");proxy.dance();}
    }

    结果

    在这里插入图片描述

反射

反射允许对封装类的字段,方法,和构造函数的信息进行编程的访问

获取class对象的三种方法

  • Class.forName(“全类名”);全类名:包名+类名

    最为常用

  • 类名.class

    一般更多的是当作参数传递

  • 对象.getClass()

    有一定的局限性,当我们已经有了该类的对象才可以使用

反射获取构造方法

获取Class对象Class
构造方法constructor
字段(成员变量)Field
成员方法Method
package bean;import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Parameter;public class MyReflect {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {//获取字节码文件对象Class clazz = Class.forName("bean.Student");//获取构造方法System.out.println("获取所有的public修饰的构造方法");Constructor[] constructors = clazz.getConstructors();for(Constructor c : constructors){System.out.println(c);}System.out.println("获取所有的构造方法");Constructor[] declaredConstructor = clazz.getDeclaredConstructors();for(Constructor c : declaredConstructor){System.out.println(c);}System.out.println("获取单个的构造方法(空参构造)");Constructor declaredConstructor1 = clazz.getDeclaredConstructor();System.out.println(declaredConstructor1);System.out.println("获取单个构造方法(一个参数的,该参数为形参的字节码)");Constructor declaredConstructor2 = clazz.getDeclaredConstructor(String.class);System.out.println(declaredConstructor2);Constructor declaredConstructor3 = clazz.getDeclaredConstructor(String.class, int.class);System.out.println(declaredConstructor3);System.out.println("获取权限修饰符");int modifiers = declaredConstructor3.getModifiers();System.out.println("权限修饰符:"+modifiers);System.out.println("获取参数类型");Parameter[] parameters = declaredConstructor3.getParameters();for (Parameter parameter : parameters) {System.out.println(parameter);}System.out.println("创建对象");Object stu = declaredConstructor3.newInstance("张三", 18);System.out.println(stu);//临时取消权限校验:class.setAccessible(true)}
}

输出结果

获取所有的public修饰的构造方法
public bean.Student(java.lang.String,int)
public bean.Student(int)
public bean.Student()
获取所有的构造方法
public bean.Student(java.lang.String,int)
public bean.Student(int)
protected bean.Student(java.lang.String)
public bean.Student()
获取单个的构造方法(空参构造)
public bean.Student()
获取单个构造方法(一个参数的,该参数为形参的字节码)
protected bean.Student(java.lang.String)
public bean.Student(java.lang.String,int)
获取权限修饰符
权限修饰符:1
获取参数类型
java.lang.String arg0
int arg1
创建对象
Student{name='张三', age=18}

在java中权限修饰符是用整数来表示的,如图所示:public == 1,private= == 2

在这里插入图片描述
)

反射获取成员变量

package bean;import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Parameter;
import java.sql.SQLOutput;public class MyReflect {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {//获取字节码文件对象Class clazz = Class.forName("bean.Student");System.out.println("获取所有成员变量");Field[] declaredFields = clazz.getDeclaredFields();for (Field declaredField : declaredFields) {System.out.println(declaredField);}System.out.println("获取所有的公共的成员变量");Field[] fields = clazz.getFields();for (Field field : fields) {System.out.println(field);}System.out.println("获取单个成员变量");Field name = clazz.getField("name");System.out.println(name);System.out.println("获取成员变量的权限修饰符");int modifiers = name.getModifiers();System.out.println(modifiers);System.out.println("获取成员变量名:");System.out.println(name.getName());System.out.println("获取数据类型");Class<?> type = name.getType();System.out.println(type);Student s = new Student("张三",18);System.out.println("获取成员变量的值");Object val = name.get(s);System.out.println(val);System.out.println("修改变量的值");name.set(s,"李四");Object val2 = name.get(s);System.out.println(val2);}
}

输出结果:

获取所有成员变量
public java.lang.String bean.Student.name
private int bean.Student.age
获取所有的公共的成员变量
public java.lang.String bean.Student.name
获取单个成员变量
public java.lang.String bean.Student.name
获取成员变量的权限修饰符
1
获取成员变量名:
name
获取数据类型
class java.lang.String
获取成员变量的值
张三
修改变量的值
李四

获取成员方法

实例代码:

package bean;import java.lang.reflect.*;
import java.sql.SQLOutput;public class MyReflect {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {//获取字节码文件对象Class clazz = Class.forName("bean.Student");System.out.println("获取所有的public方法对象,包括父类中的公共方法");Method[] methods = clazz.getMethods();for (Method method : methods) {System.out.println(method);}System.out.println("获取本类所有的方法包含私有的方法(不能获取父类的)");Method[] declaredMethods = clazz.getDeclaredMethods();for (Method declaredMethod : declaredMethods) {System.out.println(declaredMethod);}System.out.println("获取指定方法");Method eat = clazz.getMethod("eat", String.class);System.out.println(eat);System.out.println("获取方法的修饰符");int modifiers = eat.getModifiers();System.out.println(modifiers);System.out.println("获取方法的名字");String name = eat.getName();System.out.println(name);System.out.println("获取方法的形参");Parameter[] parameters = eat.getParameters();for (Parameter parameter : parameters) {System.out.println(parameter);}System.out.println("获取方法的返回值");Class<?> returnType = eat.getReturnType();System.out.println(returnType);System.out.println("获取方法的抛出的异常");Class[] exceptionTypes = eat.getExceptionTypes();for (Class exceptionType : exceptionTypes) {System.out.println(exceptionType);}System.out.println("方法的运行。。。。");Student stu = new Student("张三",18);/*invoke方法中:第一个参数:用obj对象调用该方法,方法的调用者第二个参数:调用该方法传递的参数(没有就不写)返回值:没有就不写*/Object res = eat.invoke(stu, "酸菜");//返回值为该方法的返回值System.out.println(res);}
}

运行结果:

获取所有的public方法对象,包括父类中的公共方法
public java.lang.String bean.Student.getName()
public java.lang.String bean.Student.toString()
public void bean.Student.setName(java.lang.String)
public int bean.Student.getAge()
public java.lang.String bean.Student.eat(java.lang.String) throws java.io.IOException,java.lang.NullPointerException,java.io.FileNotFoundException
public void bean.Student.setAge(int)
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
public final void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
获取本类所有的方法包含私有的方法(不能获取父类的)
public java.lang.String bean.Student.getName()
public java.lang.String bean.Student.toString()
private void bean.Student.sleep()
public void bean.Student.setName(java.lang.String)
public int bean.Student.getAge()
public java.lang.String bean.Student.eat(java.lang.String) throws java.io.IOException,java.lang.NullPointerException,java.io.FileNotFoundException
public void bean.Student.setAge(int)
获取指定方法
public java.lang.String bean.Student.eat(java.lang.String) throws java.io.IOException,java.lang.NullPointerException,java.io.FileNotFoundException
获取方法的修饰符
1
获取方法的名字
eat
获取方法的形参
java.lang.String arg0
获取方法的返回值
class java.lang.String
获取方法的抛出的异常
class java.io.IOException
class java.lang.NullPointerException
class java.io.FileNotFoundException
方法的运行。。。。
吃酸菜
吃饱了
  • 反射的作用

    获取一个类的所有信息,得到信息之后,再去执行其他的业务逻辑

lic java.lang.String bean.Student.eat(java.lang.String) throws java.io.IOException,java.lang.NullPointerException,java.io.FileNotFoundException
获取方法的修饰符
1
获取方法的名字
eat
获取方法的形参
java.lang.String arg0
获取方法的返回值
class java.lang.String
获取方法的抛出的异常
class java.io.IOException
class java.lang.NullPointerException
class java.io.FileNotFoundException
方法的运行。。。。
吃酸菜
吃饱了


* 反射的作用获取一个类的所有信息,得到信息之后,再去执行其他的业务逻辑结合配置文件,动态的创建对象并调用方法

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

149基于matlab的A星算法和PSO算法实现路径规划动画演示

基于matlab的A星算法和PSO算法实现路径规划动画演示&#xff0c;具有GUI界面&#xff0c;可自主生成障碍物。移动靶路径规划。程序已调通&#xff0c;可直接运行。 149 matlab A星算法 PSO算法 路径规划 (xiaohongshu.com)

向刻苦耐劳乐观向上的青年致敬

今晨互联网上的国际时事新闻报道&#xff0c;显得越来越真假难辨&#xff1b;特别是对俄乌战争、以巴战争、中美俄日朝印越和欧盟各国关系的新闻报道&#xff0c;可谓朝三暮四&#xff0c;一日多变&#xff0c;令人不知谁家的报道可信&#xff0c;便绕道行&#xff0c;不议为妙…

C++(11)——内存管理

C内存分布 我们先看一段代码以及相关问题。 这道题的答案是多少呢&#xff1f; 答案在这里哦&#xff0c;看一下有没有问题呀。如果这么简单的题做错了&#xff0c;怕不是要被电击一下。 C内存管理方式 我们知道C语言中动态内存管理的方式是 malloc realloc calloc free 这几…

嵌入式学习第三篇——51单片机

目录 1&#xff0c;嵌入式系统 1&#xff0c;嵌入式系统的定义 2&#xff0c;单片机的定义 2&#xff0c;51单片机 1&#xff0c;开发环境 2&#xff0c;开发板使用的基本思路 1&#xff0c;查看原理图&#xff0c;查看芯片手册 2&#xff0c;获得调用硬件的管…

【js逆向】scrapy基础

目录 一, 爬虫工程化 二, scrapy简介 三, Scrapy工作流程(重点) 四, scrapy安装 4.1 pip 安装 4.2 wheel安装 五, Scrapy实例 六, 自定义数据传输结构item 七, scrapy使用小总结 一, 爬虫工程化 在之前的学习中我们已经掌握了爬虫这门技术需要的大多数的技术点, 但是我…

OpenCV学习记录——形态学处理

文章目录 前言一、腐蚀和膨胀二、高级形态学运算三、具体应用代码 前言 形态学是图像处理中最常用的技术之一&#xff0c;它主要用于从图像中提取有意义的形状信息&#xff0c;例如边界和连通区域&#xff0c;以便后续的识别工作能够捕捉到目标对象最重要的形状特征。此外&…

车载测试Vector工具CANoe——常见问题汇总(下)

车载测试Vector工具CANoe——常见问题汇总(下) 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师(Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一…

elementUI中el-tree组件单选没有复选框时,选中、current-node-key高亮、刷新后保留展开状态功能的实现

目录 一、代码实现1. 属性了解 &#xff08;[更多](https://element.eleme.cn/#/zh-CN/component/tree)&#xff09;2. 实现步骤3.代码示例 二、 效果图 一、代码实现 1. 属性了解 &#xff08;更多&#xff09; node-key 每个树节点用来作为唯一标识的属性&#xff0c;整棵树…

发布5-JRT在Linux开发

JRT作为全信创支持的架构&#xff0c;设计之初就是计划完全能脱离Win开发和运行的&#xff0c;设计目标不仅仅是发布程序能脱Win&#xff0c;开发自己也要能脱Win。那么就不能依赖一些只能在Windows下运行或者好使的工具。JRTClient基于javafx开发、JRTBrowser基于Electron开发…

List集合接口的介绍和使用

一.关于List集合类的继承关系图 List接口继承了Collection接口&#xff0c;而List接口下有三个重要的实现类:ArrayList&#xff0c;LinkedList&#xff0c;Vector 二.List接口的基本介绍 1.List接口是Collection接口的子接口2.存入List集合中的元素是有序的&#xff08;即添加…

SVDiff: Compact Parameter Space for Diffusion Fine-Tuning——【论文笔记】

本文发表于ICCV 2023 论文地址&#xff1a;ICCV 2023 Open Access Repository (thecvf.com) 官方代码&#xff1a;mkshing/svdiff-pytorch: Implementation of "SVDiff: Compact Parameter Space for Diffusion Fine-Tuning" (github.com) 一、Introduction 最近几…

Xmind 2023 下载安装教程,保姆级教程,小白也能轻松搞定,附安装包

前言 XMind 是一款非常实用的思维导图软件&#xff0c;应用全球最先进的Eclipse RCP 软件架构&#xff0c;全力打造易用、高效的可视化思维软件&#xff0c;强调软件的可扩展、跨平台、稳定性和性能&#xff0c;致力于使用先进的软件技术帮助。 准备工作 1、Win7 及以上系统…