Java基础10(反射)

                                      Java基础10(反射)

1 什么是反射

官方解释:反射(reflection)技术通常被用来检测和改变应用程序在 Java 虚拟机中的行为表现。它是一个相对而言比较高级的技术,反射是一种强有力的技术特性,因此可以使得应用程序突破一些藩篱,执行一些常规手段无法企及的目的。通俗理解就是:反射是一种非常规手段,能在程序运行时修改程序的行为,使用有风险,需谨慎。反射可以被视为动态语言,反射机制允许程序再执行期间借助反射的API来获取任意类的内部信息。

反射的功能:①在运行时判断对象所属类②在运行时通过构造器获取对象的实例③在运行时获取类的成员变量(属性),方法等④通过反射获取类中的成员属性,方法。

反射涉及要的一些类

描述

         java.lang.Class

反射的源头,Class类的实例表示正在运行的java应用程序的类和接口

      java.lang.reflect.Field

提供有关类或接口的属性信息及动态范围权限,可以理解为封装了反射类属性的类

    java.lang.reflect.Method

提供有关类或接口的单独某个方法的信息

java.lang.reflect.Constructor

提供类的单个构造方法的信息以及他的访问权限

2 理解Class类,实例化Class类实例

Class类是反射的源头。注意要和类的概念区分开来,Class类是一个实实在在的类,在 java.lang下有个Class.java的文件和我们自己定义的类一样,Class对象就是这个类的实例。Class类是继承了Object的特殊类,他的内部可以记录类的成员,接口等信息,可以理解为Class是一个用来表示类的类。

java是运行在JVM上的,我们写好的类经过编译器编译后会生成.class文件。在运行期间,当我们要实例化一个类时,会先在内存中查看是否存在这个类,存在的话就直接创建类实例,如果没有的话就会就会去加载这个类,当加载一个类或者类加载器的defineClass()被JVM调用,便会为这个类产生一个class对象(一个Class类的实例),用来表示这个类,该类所有实例都共同拥有这个Class对象,而且是唯一的。

在java中,类是用来描述信息的,写明了有哪些内部的属性及接口,相当于定义了一套规则。Class对象被用来对类的情况进行表述的一个实例,类的实例表征,可以理解为对类的图形化,这样JVM才看的懂,看做模板。类的实例化对象,就是通过模版,开辟出的一块内存进行实际的使用。

创建Class类实例:

(1)调用运行时类本身的.class属性。如Class clazz = String.class

(2)通过运行时类的对象。如:Person p = new Person(); Class c = p.getClass();

(3)通过Class类的静态方法forName(String className)。 如: Class.forName(“包名.类名”)

(4)通过JVM类加载器。如:ClassLoader c = this.getClass().getClassLoader(); Class clazz = c.getClass();

Object中有个getClass()方法获得运行时类。

3 运行时创建类(Class)的对象,并获得类的完整结构

public class TestReflect {@Testpublic void test() throws Exception {Class clazz = Class.forName("month201906.day13.Person");Person p = (Person) clazz.newInstance();// 获得包名Package package1 = clazz.getPackage();String packName = package1.getName();System.out.println(packName);// 获得类名System.out.println(clazz.getSimpleName());// 获得属性名及其权限修饰符Field[] fields = clazz.getDeclaredFields();for (Field field : fields) {System.out.println(Modifier.toString(field.getModifiers()) + "---" + field.getName());}// 获得方法名及其权限修饰符Method[] methods = clazz.getDeclaredMethods();for (Method method : methods) {System.out.println(Modifier.toString(method.getModifiers()) + "---" + method.getName());}// 获得父类System.out.println(clazz.getSuperclass());// 获得注解Annotation[] annotations = clazz.getAnnotations();for (Annotation annotation : annotations) {System.out.println(annotation);}// 获取接口Class[] interfaces = clazz.getInterfaces();for (Class inter : interfaces) {System.out.println(inter);}}
}@Target({ TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE })
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {String name() default "zhujie";
}class Work {String worker;public void doWorker() {System.out.println("工作");}
}@MyAnnotation(name = "注解")
class Person extends Work implements Serializable {public String name;int age;private String gender;protected int score;public Person() {System.out.println("无参构造");}public Person(String name, int age) {this.name = name;this.age = age;}public Person(String name, int age, String gender, int score) {this.name = name;this.age = age;this.gender = gender;this.score = score;}private String Method1(String name, int age, String gender, int score) {this.name = name;this.age = age;this.gender = gender;this.score = score;return name;}public String Method2() {return "Person [name=" + name + ", age=" + age + ", gender=" + gender + ", score=" + score + "]";}public static void Method3() {System.out.println("Method3 static");}private void Method4() {System.out.println("Method4 private");}protected void Method5() {System.out.println("Method5 protected");}void Method6() {System.out.println("Method6 null");}public void Method7() {System.out.println("Method6 public");}@Overridepublic String toString() {return "Person [name=" + name + ", age=" + age + ", gender=" + gender + ", score=" + score + "]";}}

 

4 通过反射获取类的指定属性、方法、构造器

public class TestReflect {@Testpublic void test1() throws Exception{Class clazz = Class.forName("month201906.day13.Person");Person p = (Person) clazz.newInstance();//获取指定构造器System.out.println(clazz.getDeclaredConstructor());//有参构造Constructor<Person> con = clazz.getDeclaredConstructor(String.class,int.class,String.class,int.class);Person newInstance = con.newInstance("小明",18,"男",1000);System.out.println(newInstance);//获取指定属性Field name = clazz.getDeclaredField("name");//调用属性name.set(p, "小红");System.out.println(p);Field gender = clazz.getDeclaredField("gender");gender.setAccessible(true);gender.set(p, "女");System.out.println(p);//获取指定方法Method method1 = clazz.getDeclaredMethod("Method1", String.class,int.class,String.class,int.class);//调用方法method1.setAccessible(true);method1.invoke(p, "张三",20,"男",5000);System.out.println(p);//调用方法Method method4 = clazz.getDeclaredMethod("Method4");method4.setAccessible(true);method4.invoke(p);}}

5 动态代理

public class TestDynamicProxy {public static void main(String[] args) {RealMothod1 real = new RealMothod1();MyInvocationHandler inv1 = new MyInvocationHandler(real);// 获取代理对象pubMothod1 obj = (pubMothod1) inv1.getObj();obj.action();RealMothod2 r = new RealMothod2();MyInvocationHandler inv2 = new MyInvocationHandler(r);// 获取代理对象pubMothod2 pub = (pubMothod2) inv2.getObj();pub.show();}
}// 公共方法
interface pubMothod1 {void action();
}interface pubMothod2 {void show();
}// 被代理类1
class RealMothod1 implements pubMothod1 {@Overridepublic void action() {System.out.println("被代理类1号");}}// 被代理类2
class RealMothod2 implements pubMothod2 {@Overridepublic void show() {System.out.println("被代理类2号");}
}// 代理类的处理类   1.创建代理对象 ,2.调用代理对象代理的方法
class MyInvocationHandler implements InvocationHandler {// 被代理类的对象的声明,代理被代理类的对象Object obj; // 给被代理对象 初始化public MyInvocationHandler(Object obj) {this.obj = obj;}// 代理对象 ,代理对象调用重写的那个方法,自动调用invokepublic Object getObj() {return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("我是invoke");// 反射 "被"代理对象的方法Object object = method.invoke(obj, args);return object;}}

 

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

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

相关文章

05.序列模型 W1.循环序列模型(作业:手写RNN+恐龙名字生成)

文章目录作业1&#xff1a;建立你的循环神经网络1. RNN 前向传播1.1 RNN 单元1.2 RNN 前向传播2. LSTM 网络2.1 LSTM 单元2.2 LSTM 前向传播3. RNN 反向传播3.1 基础 RNN 反向传播3.2 LSTM 反向传播3.3 LSTM RNN网络反向传播作业2&#xff1a;字符级语言模型&#xff1a;恐龙岛…

给年轻工程师的十大忠告

给年轻工程师的十大忠告 转自http://blog.163.com/tgyeboy02126/blog/static/167507500201191102114940/诸位&#xff0c;咱当电子工程师也是十余年了&#xff0c;不算有出息&#xff0c;环顾四周&#xff0c;也没有看见几个有出息的&#xff01;回顾工程师生涯&#xff0c;感…

11.MYSQL高级(一)

1.账户管理 在生产环境下操作数据库时&#xff0c;绝对不可以使用root账户连接&#xff0c;而是创建特定的账户&#xff0c;授予这个账户特定的操作权限&#xff0c;然后连接进行操作&#xff0c;主要的操作就是数据的crud MySQL账户体系&#xff1a;根据账户所具有的权限的不…

SQL2008中Merge的用法

SQL2008中Merge的用法 在SQL2008中&#xff0c;新增了一个关键字&#xff1a;Merge&#xff0c;这个和Oracle的Merge的用法差不多&#xff0c;只是新增了一个delete方法而已。下面就是具体的使用说明&#xff1a; 首先是对merge的使用说明&#xff1a; merge [into][目标表]usi…

LeetCode 1146. 快照数组(哈希map + 有序map)

文章目录1. 题目2. 解题1. 题目 实现支持下列接口的「快照数组」- SnapshotArray&#xff1a; SnapshotArray(int length) - 初始化一个与指定长度相等的 类数组 的数据结构。初始时&#xff0c;每个元素都等于 0。void set(index, val) - 会将指定索引 index 处的元素设置为…

12.MYSQL高级(二)

1.视图&#xff08;重点 视图本质就是对查询的封装&#xff0c;定义视图&#xff0c;建议以v_开头 create view 视图名称 as select语句; 例&#xff1a;创建视图&#xff0c;查询学生对应的成绩信息 create view v_stu_sco as select students.*,scores.score from scores in…

1.NoSQL与MongoDB简介

NoSQL&#xff1a;非关系型数据库 使用范围&#xff1a;论坛、博客、sns、微博 NoSQL优势&#xff1a; 1.易扩展 2.数据量大&#xff0c;高性能 3.灵活的数据模型 4.高可用 MongoDB特点 模式自由 :可以把不同结构的文档存储在同一个数据库里 面向集合的存储&#xff1a;…

LeetCode 825. 适龄的朋友(计数排序+前缀和)

文章目录1. 题目2. 解题1. 题目 人们会互相发送好友请求&#xff0c;现在给定一个包含有他们年龄的数组&#xff0c;ages[i] 表示第 i 个人的年龄。 当满足以下任一条件时&#xff0c;A 不能给 B&#xff08;A、B不为同一人&#xff09;发送好友请求&#xff1a; age[B] <…

[转]java 组播

1. 组播知识介绍&#xff1a; http://blog.csdn.net/happy_david/article/details/1569209 2. java 组播实现&#xff1a;来自&#xff1a; http://blog.csdn.net/a352193394/article/details/7395600 下面来演示一下使用Java Socket的组播类实现一个组播的小案例 首先是接收端…

2.MongoDB基本操作

数据库命令 连接成功后&#xff0c;默认使用test数据库 查看当前数据库名称&#xff1a;db 查看所有数据库名称&#xff1a;show dbs 切换数据库&#xff0c;如果数据库不存在也并不创建&#xff0c;直到插入数据或创建集合时数据库才被创建&#xff1a;use 数据库名称 删除当…

LeetCode 954. 二倍数对数组(map计数)

文章目录1. 题目2. 解题1. 题目 给定一个长度为偶数的整数数组 A&#xff0c;只有对 A 进行重组后可以满足 对于每个 0 < i < len(A) / 2&#xff0c;都有 A[2 * i 1] 2 * A[2 * i] 时&#xff0c;返回 true&#xff1b;否则&#xff0c;返回 false。 示例 1&#xf…

jsp用tags传递参数

<computer:trangleTag sideA"12" sideB"12" sideC"12"/>表示以字符串传递sideABC <computer:trangleTag sideA“uname” sideB“ustudentcode” sideC“upassword” />表示传递的字符串是uname&#xff0c;ustudentcode&#xff0c;…

3.MongoDB数据查询

数据查询 基本查询 方法find()&#xff1a;查询&#xff1a;db.集合名称.find({条件文档}) 方法findOne()&#xff1a;查询&#xff0c;只返回第一个&#xff1a;db.集合名称.findOne({条件文档}) 方法pretty()&#xff1a;将结果格式化&#xff1a;db.集合名称.find({条件文档…

Java增强之并发编程

Java增强之并发编程 1 多线程 1.1 进程及线程 程序启动的时候&#xff0c;电脑会把这个程序加载到内存&#xff0c;在内存中需要给当前的程序分配一段的独立运行的空间&#xff0c;这个空间就专门负责这个程序的运行。每个应用程序运行都需要在内存中有自己独立的运行空间&a…

LeetCode 732. 我的日程安排表 III(差分思想)

文章目录1. 题目2. 解题1. 题目 实现一个 MyCalendar 类来存放你的日程安排&#xff0c;你可以一直添加新的日程安排。 MyCalendar 有一个 book(int start, int end)方法。它意味着在start到end时间内增加一个日程安排&#xff0c;注意&#xff0c;这里的时间是半开区间&…

4.聚合aggregate

聚合(aggregate)主要用于计算数据&#xff0c;类似sql中的sum()、avg() 语法&#xff1a;db.集合名称.aggregate({管道:{表达式}}) 管道 管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的输入 ps ajx | grep mongo 常用管道 $group&#xff1a;将集合中的…

WebView退出时停止视频播放

网上比较流行的方法: 在activity的onPause函数中调用webview的onPause函数。 弊端:视频虽然停止播放但是还是在从网上加载数据(观察流量统计); 比较好的方法: 在activity的onPause函数中调用webview的onPause函数。 在activity的onDestroy函数中webview.loadUrl("file:///…

5.MongoDB索引

mongodb支持索引&#xff0c;以提升查询速度 步骤一&#xff1a;创建大量数据 在命令行中执行如下代码&#xff0c;向集合中插入10万条文档 注意&#xff1a;不要在图形界面中执行&#xff0c;因为软件原因无法插入10万条数据就会中断执行 for(i0;i<100000;i){ db.t1.in…

Hadoop学习之整体介绍及环境搭建

Hadoop学习之整体介绍及环境搭建 1 大数据概述 1.1 什么是大数据 数据(data)是事实或观察的结果&#xff0c;是对客观事物的逻辑归纳&#xff0c;是用于表示客观事物的未经加 工的的原始素材。 大数据&#xff1a;传统处理方式无法解决的不仅大而且复杂的数据集的存储和计算…

05.序列模型 W2.自然语言处理与词嵌入

文章目录1. 词汇表征2. 使用词嵌入3. 词嵌入的特性4. 嵌入矩阵5. 学习词嵌入6. Word2Vec7. 负采样8. GloVe 词向量9. 情感分类10. 词嵌入除偏作业参考&#xff1a;吴恩达视频课深度学习笔记自然语言处理与词嵌入 Natural Language Processing and Word Embeddings 1. 词汇表征…