先看再点赞,给自己一点思考的时间,如果对自己有帮助,微信搜索【程序职场】关注这个执着的职场程序员。
价值: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反射机制太经典!不看后悔!的更多相关文章

  1. 面试题:了解MySQL的Flush-List吗?顺便说一下脏页的落盘机制!(文末送书)

    Hi,大家好!我是白日梦! 今天我要跟你分享的MySQL话题是:"了解Flush-List吗?顺便说一下脏页的落盘机制!(文末送书)" 本文是MySQL专题的第 8 篇,共110篇 ...

  2. 冰河又一MySQL力作出版(文末送书)!!

    写在前面 继<海量数据处理与大数据技术实战>之后,冰河的又一力作<MySQL技术大全:开发.优化与运维实战>出版,相信这本书对任何想系统学习MySQL的小伙伴来说,都会带来实质 ...

  3. 菜鸟学Java(十四)——Java反射机制(一)

    说到反射,相信有过编程经验的人都不会陌生.反射机制让Java变得更加的灵活.反射机制在Java的众多特性中是非常重要的一个.下面就让我们一点一点了解它是怎么一回事. 什么是反射 在运行状态中,对于任意 ...

  4. 一文带你了解Java反射机制

    想要获取更多文章可以访问我的博客 - 代码无止境. 上周上班的时候解决一个需求,需要将一批数据导出到Excel.本来公司的中间件组已经封装好了使用POI生成Excel的工具方法,但是无奈产品的需求里面 ...

  5. Java反射机制demo(四)—获取一个类的父类和实现的接口

    Java反射机制demo(四)—获取一个类的父类和实现的接口 1,Java反射机制得到一个类的父类 使用Class类中的getSuperClass()方法能够得到一个类的父类 如果此 Class 表示 ...

  6. Java反射机制的浅显理解(这篇文章还没写好,留个草稿给自己看的)

    目前只是有一个大概的理解,先把自己感觉容易立即的概念放这里,等以后结合实际工作理解深刻了再来补充. 一.什么是Java反射机制?(多种定义) 1. JAVA反射机制是在运行状态中,对于任意一个类,都能 ...

  7. 如何高效、快速学习Flutter?如何避坑?(文末送服福利)

    稳住,今天是周末,不过我今天要上班....啊..啊... 对于 Flutter 我没有太多的发言权,不过GSY是对 Flutter 充分理解并精深掌握的前辈了,所以转一篇他对 Flutter 的一些解 ...

  8. 一文看懂 ZooKeeper ,面试再也不用背八股(文末送PDF)

    ZooKeeper知识点总结 一.ZooKeeper 的工作机制 二.ZooKeeper 中的 ZAB 协议 三.数据模型与监听器 四.ZooKeeper 的选举机制和流程 本文将以如下内容为主线讲解 ...

  9. 11.Java反射机制 哦对了,前面的序号来自随笔关于编程之路的思索第一篇

    基本概念 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? 答案是肯定的. 这种动态获取类的信息以及动态调用对象的方法的功能来自于J ...

随机推荐

  1. java 文件上传下载

    翻新十年前的老项目,文件上传改为调用接口方式,记录一下子~~~ java后台代码: //取配置文件中的上传目录 @Value("${uploadPath}") String pat ...

  2. html-新闻滚动条

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. grasshopper DataTree 树形数据以及Graft Flatten Simplify的理解

    问题的来源: 要在grasshopper里面输出 类似于二维数组的数据 但是在 grasshopper里的 C# 电池里面,无法显示 二维ArrayList里面的数据. 在 C# 电池里参考这个帖子: ...

  4. Timer定时器开发

    Timer定时器开发 定时器的作用是不占线程的等待一个确定时间,同样通过callback来通知定时器到期. 参考:https://github.com/sogou/workflow 定时器的创建 同样 ...

  5. vue中dom节点转图片

    今天项目中有个需求,需要将页面的一部分转为图片,相当于存证之类的 然后我查阅了下百度,发现了几种可行的方法,特此来记录下 1.html2canvas插件 安装:npm install --save h ...

  6. 菜鸟刷题路(随缘刷题):leetcode88

    lc88 class Solution { public void merge(int[] nums1, int m, int[] nums2, int n) { int i = m - 1, j = ...

  7. Task02:基础查询与排序

    2.1 SELECT语句基础 2.1.1 从表中选取数据 SELECT语句 从表中选取数据时需要使用SELECT语句,也就是只从表中选出(SELECT)必要数据的意思.通过SELECT语句查询并选取出 ...

  8. 基于kerberos的hadoop安全集群搭建

    目录 前置条件 kerberos相关 给hadoop各组件创建kerberos账号 将这些账号做成keytab core-site.xml HDFS datanode的安全配置 证书生成和安装 hdf ...

  9. MySQL 最佳实践 —— 高效插入数据

    当你需要在 MySQL 数据库中批量插入数百万条数据时,你就会意识到,逐条发送 INSERT 语句并不是一个可行的方法. MySQL 文档中有些值得一读的 INSERT 优化技巧. 在这篇文章里,我将 ...

  10. 我试了试用 SQL查 Linux日志,好用到飞起

    大家好,我是小富~ 最近发现点好玩的工具,迫不及待的想跟大家分享一下. 大家平时都怎么查Linux日志呢? 像我平时会用tail.head.cat.sed.more.less这些经典系统命令,或者aw ...