先看再点赞,给自己一点思考的时间,如果对自己有帮助,微信搜索【程序职场】关注这个执着的职场程序员。
价值:Java技能,面试经验指导,简历优化,职场规划指导,技能提升方法,讲不完的职场故事,个人成长经验。
01
概念
反射是Java的特征之一,是一种间接操作目标对象的机制,核心是JVM在运行的时候才动态加载类,并且对于任意一个类,都能够知道这个类的所有属性和方法,调用方法/访问属性,不需要提前在编译期知道运行的对象是谁,他允许运行中的Java程序获取类的信息,并且可以操作类或对象内部属性。
程序中对象的类型一般都是在编译期就确定下来的,而当我们的程序在运行时,可能需要动态的加载一些类,这些类因为之前用不到,所以没有加载到jvm,这时,使用Java反射机制可以在运行期动态的创建对象并调用其属性,它是在运行时根据需要才加载。
02
用途
只是知道概念还不能更明白反射到底是什么?,那么反射都在哪些用途上使用呢?我们开发中哪些情况下使用?
一般来说反射是用来做框架的,做一些抽象度比较高的底层代码。
反射是框架设计的灵魂。
反射都有哪些用途呢?
1、首先就是反编译,反编译是 .class-->.java
2、通过反射机制访问java对象的属性,方法,构造方法等
3、当我们在使用IDE,比如Ecplise时,当我们输入一个对象或者类,并想调用他的属性和方法是,一按点号,编译器就会自动列出他的属性或者方法,这里就是用到反射。
4、反射最重要的用途就是开发各种通用框架。
03
解剖类
我们知道一个类里一般有构造函数、方法、成员变量(字段/属性)。
Class对象提供了如下常用方法:
public Constructor getConstructor(Class<?>…parameterTypes)
public Method getMethod(String name,Class<?>… parameterTypes)
public Field getField(String name)
public Constructor getDeclaredConstructor(Class<?>…parameterTypes)
public Method getDeclaredMethod(String name,Class<?>… parameterTypes)
public Field getDeclaredField(String name)
这些方法分别用于帮咱们从类中解剖出构造函数、方法和成员变量(属性)。
然后把解剖出来的部分,分别用Constructor、Method、Field对象表示。
首先要明白一点,我们写的代码是存储在后缀名是 .java的文件里的,但是它会被编译,最终真正去执行的是编译后的 .class文件。
Java是面向对象的语言,一切皆对象,所以java认为 这些编译后的 class文件,这种事物也是一种对象,它也给抽象成了一种类,这个类就是Class,大家可以去AIP里看一下这个类。
大家可以查看api
04
常用类
Java.lang.Class;
Java.lang.reflect.Constructor;
Java.lang.reflect.Field;
Java.lang.reflect.Method;
Java.lang.reflect.Modifier;
05
实例
1,反射类中的方法
添加一个Person类,添加几种参数的方法。
package com.cj.test;
import java.util.Date;
public class Person {
public Person(){
System.out.println("默认的无参构造方法执行了");
}
public Person(String name){
System.out.println("姓名:"+name);
}
public Person(String name,int age){
System.out.println(name+"="+age);
}
private Person(int age){
System.out.println("年龄:"+age);
}
public void m1() {
System.out.println("m1");
}
public void m2(String name) {
System.out.println(name);
}
public String m3(String name,int age) {
System.out.println(name+":"+age);
return "aaa";
}
private void m4(Date d) {
System.out.println(d);
}
public static void m5() {
System.out.println("m5");
}
public static void m6(String[] strs) {
System.out.println(strs.length);
}
public static void main(String[] args) {
System.out.println("main");
}
}
下面我们来看一下调用。
package com.cj.test;
import java.lang.reflect.Method;
import java.util.Date;
import org.junit.Test;
public class Test1 {
@Test//public void m1()
public void test1() throws Exception{
Class clazz = Class.forName("com.cj.test.Person");
Person p = (Person)clazz.newInstance();
Method m = clazz.getMethod("m1", null);
m.invoke(p, null);
}
@Test//public void m2(String name)
public void test2() throws Exception{
Class clazz = Person.class;
Person p = (Person) clazz.newInstance();
Method m = clazz.getMethod("m2", String.class);
m.invoke(p, "程序职场");
}
@Test//public String m3(String name,int age)
public void test3() throws Exception{
Class clazz = Person.class;
Person p = (Person) clazz.newInstance();
Method m = clazz.getMethod("m3", String.class,int.class);
String returnValue = (String)m.invoke(p, "程序职场",23);
System.out.println(returnValue);
}
@Test//private void m4(Date d)
public void test4() throws Exception{
Class clazz = Person.class;
Person p = (Person) clazz.newInstance();
Method m = clazz.getDeclaredMethod("m4", Date.class);
m.setAccessible(true);
m.invoke(p,new Date());
}
@Test//public static void m5()
public void test5() throws Exception{
Class clazz = Person.class;
Method m = clazz.getMethod("m5", null);
m.invoke(null,null);
}
@Test//private static void m6(String[] strs)
public void test6() throws Exception{
Class clazz = Person.class;
Method m = clazz.getDeclaredMethod("m6",String[].class);
m.setAccessible(true);
m.invoke(null,(Object)new String[]{"a","b"});
}
@Test
public void test7() throws Exception{
Class clazz = Person.class;
Method m = clazz.getMethod("main",String[].class);
m.invoke(null,new Object[]{new String[]{"a","b"}});
}
}
2,反射类中的属性字段
package com.cj.test;
import java.util.Date;
public class Person {
public String name="程序职场";
private int age = 18;
public static Date time;
public int getAge() {
return age;
}
public Person(){
System.out.println("默认的无参构造方法执行了");
}
public Person(String name){
System.out.println("姓名:"+name);
}
public Person(String name,int age){
System.out.println(name+"="+age);
}
private Person(int age){
System.out.println("年龄:"+age);
}
public void m1() {
System.out.println("m1");
}
public void m2(String name) {
System.out.println(name);
}
public String m3(String name,int age) {
System.out.println(name+":"+age);
return "aaa";
}
private void m4(Date d) {
System.out.println(d);
}
public static void m5() {
System.out.println("m5");
}
public static void m6(String[] strs) {
System.out.println(strs.length);
}
public static void main(String[] args) {
System.out.println("main");
}
}
结果调用。
package com.cj.test;
import java.lang.reflect.Field;
import java.util.Date;
import org.junit.Test;
public class Demo3 {
//public String name="李四";
@Test
public void test1() throws Exception{
Class clazz = Person.class;
Person p = (Person)clazz.newInstance();
Field f = clazz.getField("name");
String s = (String)f.get(p);
System.out.println(s);
//更改name的值
f.set(p, "王六");
System.out.println(p.name);
}
@Test//private int age = 18;
public void test2() throws Exception{
Class clazz = Person.class;
Person p = (Person)clazz.newInstance();
Field f = clazz.getDeclaredField("age");
f.setAccessible(true);
int age = (Integer)f.get(p);
System.out.println(age);
f.set(p, 28);
age = (Integer)f.get(p);
System.out.println(age);
}
@Test//public static Date time;
public void test3() throws Exception{
Class clazz = Person.class;
Field f = clazz.getField("time");
f.set(null, new Date());
System.out.println(Person.time);
}
}
3,反射方法的其他使用--通过反射越过泛型检查
import java.lang.reflect.Method;
import java.util.ArrayList;
/*
* 通过反射越过泛型检查
* 例如:有一个String泛型的集合,怎样能向这个集合中添加一个Integer类型的值?
*/
public class Demo {
public static void main(String[] args) throws Exception{
ArrayList<String> strList = new ArrayList<>();
strList.add("aaa");
strList.add("bbb");
// strList.add(100);
//获取ArrayList的Class对象,反向的调用add()方法,添加数据
Class listClass = strList.getClass(); //得到 strList 对象的字节码 对象
//获取add()方法
Method m = listClass.getMethod("add", Object.class);
//调用add()方法
m.invoke(strList, 100);
//遍历集合
for(Object obj : strList){
System.out.println(obj);
}
}
}
讲了这么多,赶紧试试吧,在项目使用中更方便。
本文 Github ( 码云Gitee同步) https://github.com/ProceduralZC/JavaDevGuide/tree/master/code/JavaBasic 已收录,欢迎 star。
文末送书
文末送书时刻!送的书分别是:
Node.js企业级应用开发实战(北京大学出版社提供 3本)
Redis设计与实现 (机械工业出版社提供 1本)
在此感谢北京大学出版社,机械工业出版社的支持。
送书规矩
从留言区中选中奖者,按照留言者的点赞,分享数选择,点赞,分享数高者获得书一本,累计送书 四本。时间截止9月18日的20点。
送的书籍
Node.js企业级应用开发实战
Redis设计与实现
我是【尔东双月】一枚执着的职场程序员,微信搜索【程序职场】关注我。别忘了三连啊,点赞、收藏、留言,随意给,我不挑。
注:如果文章有任何问题,欢迎毫不留情地指正。
文末送书四本 | 这篇Java反射机制太经典!不看后悔!的更多相关文章
-
面试题:了解MySQL的Flush-List吗?顺便说一下脏页的落盘机制!(文末送书)
Hi,大家好!我是白日梦! 今天我要跟你分享的MySQL话题是:"了解Flush-List吗?顺便说一下脏页的落盘机制!(文末送书)" 本文是MySQL专题的第 8 篇,共110篇 ...
-
冰河又一MySQL力作出版(文末送书)!!
写在前面 继<海量数据处理与大数据技术实战>之后,冰河的又一力作<MySQL技术大全:开发.优化与运维实战>出版,相信这本书对任何想系统学习MySQL的小伙伴来说,都会带来实质 ...
-
菜鸟学Java(十四)——Java反射机制(一)
说到反射,相信有过编程经验的人都不会陌生.反射机制让Java变得更加的灵活.反射机制在Java的众多特性中是非常重要的一个.下面就让我们一点一点了解它是怎么一回事. 什么是反射 在运行状态中,对于任意 ...
-
一文带你了解Java反射机制
想要获取更多文章可以访问我的博客 - 代码无止境. 上周上班的时候解决一个需求,需要将一批数据导出到Excel.本来公司的中间件组已经封装好了使用POI生成Excel的工具方法,但是无奈产品的需求里面 ...
-
Java反射机制demo(四)—获取一个类的父类和实现的接口
Java反射机制demo(四)—获取一个类的父类和实现的接口 1,Java反射机制得到一个类的父类 使用Class类中的getSuperClass()方法能够得到一个类的父类 如果此 Class 表示 ...
-
Java反射机制的浅显理解(这篇文章还没写好,留个草稿给自己看的)
目前只是有一个大概的理解,先把自己感觉容易立即的概念放这里,等以后结合实际工作理解深刻了再来补充. 一.什么是Java反射机制?(多种定义) 1. JAVA反射机制是在运行状态中,对于任意一个类,都能 ...
-
如何高效、快速学习Flutter?如何避坑?(文末送服福利)
稳住,今天是周末,不过我今天要上班....啊..啊... 对于 Flutter 我没有太多的发言权,不过GSY是对 Flutter 充分理解并精深掌握的前辈了,所以转一篇他对 Flutter 的一些解 ...
-
11.Java反射机制 哦对了,前面的序号来自随笔关于编程之路的思索第一篇
基本概念 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? 答案是肯定的. 这种动态获取类的信息以及动态调用对象的方法的功能来自于J ...
-
Java反射机制剖析(四)-深度剖析动态代理原理及总结
动态代理类原理(示例代码参见java反射机制剖析(三)) a) 理解上面的动态代理示例流程 a) 理解上面的动态代理示例流程 b) 代理接口实现类源代码剖析 咱们一起来剖析一下代理实现类($Pr ...
随机推荐
-
HDU 1004 Let the Balloon Rise(AC代码)
#include <stdio.h> #include <string.h> ][]; ]={}; int main() { int n,i,j,k,max,loc; ){ m ...
-
Chronometer控件实现的Android计时器
本文为大家演示了如何使用Chronometer控件实现Android计时器的实例. 先贴上最终的实现效果图: Android计时器实现思路 使用Chronometer控件实现计器的操作.通过设置set ...
-
Java学习笔记--脚本语言支持API
Java语言的动态性之脚本语言支持API 随着Java平台的流行,很多的脚本语言(scripting language)都可以运行在Java虚拟机啊上,其中比较流行的有JavaScript.JRuby ...
-
电脑创建WIFI/无线热点之后, 手机QQ能上浏览器不能上网
这个完全是个人经验,绝对原创,请尊重博主原创权,转载请注明转于此博客. 问题如题,大家电脑创建无线热点之后, 有的人手机会出现QQ,微信能上网, 但是浏览器或者基于浏览器的那些比如应用商店不能上网, ...
-
初学angular项目中遇到的一些问题
1.当angular渲染完成后操作DOM树方法 //当数据渲染完毕 ngApp.directive('repeatFinish', function () { return { ...
-
git入门 多人协作
当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin. 要查看远程库的信息,用git remote: $ git r ...
-
6M - 循环多少次?
我们知道,在编程中,我们时常需要考虑到时间复杂度,特别是对于循环的部分.例如, 如果代码中出现 for(i=1;i<=n;i++) OP ; 那么做了n次OP运算,如果代码中出现 fori=1; ...
-
tomcat 拒绝服务
一 尝试重新下载二进制安装包安装包 wget http://mirror.bit.edu.cn/apache/tomcat/tomcat-9/v9.0.16/bin/apache-tomcat-9.0 ...
-
Async注解的使用,异步进行代码解耦
在开发中进行代码性能的优化方式有很多种,如下单后,要发送消息推送给用户,此时可以使用消息中间件rabbitMq,或者使用异步的方式进行解耦 异步和同步的区别:比如做家务有:做饭,洗衣服,扫地,对于同步 ...
-
Redis持久化之RDB&;&;AOF的区别
在说Redis持久化之前,需要搞明白什么是数据库状态这个概念,因为持久化的就是将内存中的数据库状态保存到磁盘上.那么什么是数据库状态呢?Redis是一个key-value数据库服务器,一般默认是有16 ...