先看再点赞,给自己一点思考的时间,如果对自己有帮助,微信搜索【程序职场】关注这个执着的职场程序员。
价值: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设计与实现

我是【尔东双月】一枚执着的职场程序员,微信搜索【程序职场】关注我。别忘了三连啊,点赞、收藏、留言,随意给,我不挑。
注:如果文章有任何问题,欢迎毫不留情地指正。

最新文章

  1. MySQL 数据库的备份与恢复
  2. CentOS 6.5 升级 PHP 到5.6
  3. Ubuntu杂记——Ubuntu下用虚拟机共享上网
  4. 深入剖析tomcat之一个简单的web服务器
  5. [转]C#中的string.Format()的JS版本
  6. WinForm 窗体基本属性、公共控件
  7. leetcode日记 Product of Array Except Self
  8. 【转】libevent和基于libevent的网络编程
  9. 跟我一起云计算(6)——openAPI
  10. swift语言的学习笔记
  11. hibernate中几个接口作用
  12. ppurl
  13. 要件审判九步法及其基本价值 z
  14. CentOS下MySQL忘记root密码解决方法【转载】
  15. Mouse_event 鼠标点击
  16. HTTP协议报文、工作原理及Java中的HTTP通信技术详解
  17. 【转】 Android项目的mvc模式
  18. java----代码打包
  19. pp 总结二
  20. streamdataio 实时数据分发平台

热门文章

  1. Day029 JDK8中新日期和时间API (二)
  2. 『动善时』JMeter基础 — 30、JMeter中JSON断言详解
  3. [leetcode] 37. 解数独(Java)(dfs,递归,回溯)
  4. pika详解(三)SelectConnection及其他Connection
  5. 书列荐书 |《至关重要的关系》 【美】里德&amp;#183;霍夫曼
  6. CVPR2019目标检测论文看点:并域上的广义交
  7. AlexeyAB DarkNet YOLOv3框架解析与应用实践(三)
  8. CUDA Pro:通过向量化内存访问提高性能
  9. TensorFlow神经网络集成方案
  10. Covid经济型自主汽车