文末送书四本 | 这篇Java反射机制太经典!不看后悔!
先看再点赞,给自己一点思考的时间,如果对自己有帮助,微信搜索【程序职场】关注这个执着的职场程序员。
价值: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 的一些解 ...
- 一文看懂 ZooKeeper ,面试再也不用背八股(文末送PDF)
ZooKeeper知识点总结 一.ZooKeeper 的工作机制 二.ZooKeeper 中的 ZAB 协议 三.数据模型与监听器 四.ZooKeeper 的选举机制和流程 本文将以如下内容为主线讲解 ...
- 11.Java反射机制 哦对了,前面的序号来自随笔关于编程之路的思索第一篇
基本概念 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? 答案是肯定的. 这种动态获取类的信息以及动态调用对象的方法的功能来自于J ...
随机推荐
- kylin优化的思想
kylin的核心优势在于使用额外的空间存储预计算的结果,以换取查询时间的缩减. 所以我们要对额外的空间进行优化,并且在空间优化之后,cuboid无法完全命中时,对查询时间进行优化. 空间优化的思路就是 ...
- ASP.NET Core文件上传IFormFile于Request.Body的羁绊
前言 在上篇文章深入探究ASP.NET Core读取Request.Body的正确方式中我们探讨了很多人在日常开发中经常遇到的也是最基础的问题,那就是关于Request.Body的读取方式问题,看是简 ...
- Linux C 进程
进程 UNIX编程手册第6 7章完结 24 25 26 27 28 未完待续,可能等到期末考试结束吧 目录 进程 基础知识 内存分布 命令行参数 环境列表 获得环境 修改环境 非本地跳转 内存分配 在 ...
- openresty - nginx - 配置
local function local_print(str) local dbg = io.open("conf/lua/logs/output.txt", "a+&q ...
- 电脑华硕A455L系列,机械硬盘换成固态硬盘,光驱位改放机械硬盘
电脑一直以来都很卡,直到最近用的不舒服了,就去查查原因,发现是磁盘读取爆表!只好想起来换固态硬盘,光驱改放机械硬盘... 买的固态硬盘是个杂牌军,但是店家说工艺不错,只好将信将疑,用用再说吧. 首先确 ...
- NVIDIA GPU上的Tensor线性代数
NVIDIA GPU上的Tensor线性代数 cuTENSOR库是同类中第一个GPU加速的张量线性代数库,提供张量收缩,归约和逐元素运算.cuTENSOR用于加速在深度学习训练和推理,计算机视觉,量子 ...
- MindSpore模型精度调优实践
MindSpore模型精度调优实践 引论:在模型的开发过程中,精度达不到预期常常让人头疼.为了帮助用户解决模型调试调优的问题,为MindSpore量身定做了可视化调试调优组件:MindInsight. ...
- GVS智能照明再下一城,前方到站贵阳地铁2号线!
近期,"新基建"又频频刷屏,也为城轨交通建设快速发展提供了广阔的想象空间. 在新基建的导向作用下,越来越多城市加入地铁阵营.如果说普铁和高铁作为城市的发展窗口,那么地铁则是城市交通 ...
- postman之内建变量的基础应用
一.Postman有以下内建变量,适合一次性使用:{{$guid}}//生成GUID{{$timestamp}}//当前时间戳{{$randomInt}}//0-1000的随机整数 简单应用举例: 二 ...
- Java面试指北!13个认证授权常见面试题/知识点总结!| JavaGuide
大家好,我是 Guide哥!端午已过,又要开始工作学习啦! 我发现有很多小伙伴对认证授权方面的知识不是特别了解,搞不清 Session 认证.JWT 以及 Cookie 这些概念. 所以,根据我根据日 ...