文末送书四本 | 这篇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 ...
随机推荐
- wxPython使用指导
一.wxPython简介 这是Python一个非常不错的GUI开发库,免费.开源.跨平台,可用组件众多,借助这些组件,程序员可以快速创建完整.功能全面的用户界面,因此应用非常广泛 二.安装方式: pi ...
- nginx基础概念
nginx基础概念(100%) connection¶ 在nginx中connection就是对tcp连接的封装,其中包括连接的socket,读事件,写事件.利用nginx封装的connection, ...
- [NOIP1998 提高组] 拼数
题目描述 设有 n 个正整数 a1-an,将它们联接成一排,相邻数字首尾相接,组成一个最大的整数. 输入格式 第一行有一个整数,表示数字个数 n. 第二行有 n 个整数,表示给出的 n 个整数 a_ ...
- MySQL 5.7.33 超级详细下载安装配置测试教程(可以安装成功版)
目录 1.引言及注意事项 (1) 引言: (2) 注意: 2.MySQL下载 3.配置环境变量 4.配置my.ini文件(重点) 5.安装MySQL(重点) 6.设置密码 7.测试MySQL是否安装成 ...
- postman实现参数化执行及断言处理
一.假设需要做的测试的参数如下: 注意保存为.csv文件时一定要选择格式为UTF-8 ,避免乱码. 二.输入参数和期望结果在postman中的用法: 注意一定要通过runner的方式进行运行,选择对应 ...
- Netty 框架学习 —— ByteBuf
概述 网络数据的基本单位总是字节,Java NIO 提供了 ByteBuffer 作为它的字节容器,但这个类的使用过于复杂.Netty 的 ByteBuf 具有卓越的功能性和灵活性,可以作为 Byte ...
- 安全Web服务器
https协议: 443 端口 虚拟Server0: 1.部署 网站证书(营业执照)# cd /etc/pki/tls/certs/ # wget http://classroom.example.c ...
- 【NX二次开发】根据根据坐标系、对象旋转视图旋转视图uc6434
uc6434 (); //旋转视图 参数1:如果输入""则旋转当前工作视图参数2:1.按照ABS旋转视图.2.按照WCS选择视图.3.按照参数3旋转视图.4.按照参数4旋转视图参数 ...
- python学习笔记01-简单接触
前言:陆陆续续学习python一年多了,每次都因为各种原因中断了,希望这次可以通过记录更新的方式坚持学完一轮. 简单了解python Python是一种解释型.面向对象.动态数据类型的高级程序设计语言 ...
- echarts迁移图动态加载
迁移图 获取迁移城市的经纬度 可以调用高德的接口,实现根据地名找寻经纬度的方法 #!/usr/bin/env python3 #-*- coding:utf-8 -*- ''' 利用高德地图api实现 ...