引言

初学Java反射机制的时候,只是感觉很神奇,但是不知道学了该怎么用,所以过了一段时间就忘得差不多了;最近接触到了框架,在学习中遇到了反射,深深体会到了反射机制的神奇,回来复习了一下反射机制,写一个小总结;

概念

反射机制是什么?百度百科很好的解释了:

Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。
这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。

在这里我也就不细说概念了,在使用中你就可以慢慢明白了;

下面我来展示一下Java反射机制的基本操作;
注:为了使代码简明易看,所有的异常处理直接抛出Exception(实际应用不要这样!!)

获取类型

在Java中有一种类型叫做Class,这是一种类的类型,和String、Object一个意思,所以不要和类弄混了;

我们可以通过反射机制获取一个类的类型,返回值类型就是Class

获取类型有三种方法:

  • Class静态方法forName()
  • 对象.getClass
  • 类名.class

下面是代码演示:

// 获取不同类型(Class)的三种方式:Class静态方法forName、对象.getClass()、类名.class
// Class也是一个类类型,和String、Object一样
// java.lang.Class:Class代表整个字节码,代表一个类型,代表整个类
public class ReflectTest01 {public static void main(String[] args) throws Exception {// 第一种:通过Class的静态方法:forName获取Class类型Class c1 = Class.forName("java.lang.String"); // String类型Class c2 = Class.forName("java.lang.Object"); // Object类型System.out.println(c1 == c2); // String类型和Object类型不同, false//==============================================================// 第二种:(对象.getClass())java中任何一个对象都有这个方法:getClass(),返回值类型是Class类型Class c3 = "444".getClass(); // c5是String类型Class c4 = new Object().getClass(); // c6是Object类型System.out.println(c1 == c3); // trueSystem.out.println(c2 == c4); // true//=========================================================// 第三种:(类名.class)java中任何一种类型,包括基本数据类型,都有一个.class属性Class c5 = String.class; // String类型Class c6 = Object.class; // Object类型System.out.println(c1 == c5); // trueSystem.out.println(c2 == c6); // true}
}

这三种方法中主要留意的就是第一种,forName()方法的使用规则是:

这里需要记住forName()方法可以使对应的类加载,类加载就会执行静态代码块;
所以如果只想执行静态代码块,那么可以使用forName()方法;
为什么说这一点呢?因为JDBC注册驱动中将会用到这一点;

下面来展示一下这个特性:
forName()传入的类:

public class MyClass {static {System.out.println("静态代码块执行了!!");}
}
// 结论:如果只想要一个类的静态代码块执行,其余代码都不执行,可以使用:
// Class.forName("完整类名")
// 这个方法的执行会导致类加载,类加载时静态代码快执行
// *****这一点会在后面JDBC中用到*****
public class ReflectTest03 {public static void main(String[] args) throws Exception{// Class.forName()导致类加载,静态代码快执行Class.forName("reflect.test03.MyClass");}
}

输出:

当然这里只是简单模拟了一下,但是原理都是一样的;
结论:如果只想要一个类的静态代码块执行,其余代码都不执行,可以使用:Class.forName(“完整类名”)

实例化对象

当获取到对象类型后就可以通过该类型实例化对应的对象,用到newInstance()方法

在框架一般都是需要通过反射机制获取配置文件内容并进行操作的,通过配置文件内容可以获取不同信息,下面演示一下如何通过配置文件实例化对象;
注:这里使用.properties文件,简单易懂

创建一个.properties文件:

这个配置文件需要放到该项目的目录下,不能放到类路径(src)或者其他目录下;

import java.io.FileInputStream;
import java.util.Properties;// 通过反射机制获取配置文件内容并实例化对象
// 反射机制让程序更加灵活,符合OPC开闭原则
// 高级框架(Spring等)底层原理都是反射机制
public class ReflectTest02 {public static void main(String[] args) throws Exception{FileInputStream fis = new FileInputStream("classname.properties"); // 创建输入流Properties properties = new Properties(); // 底层实现是Map,继承了HashTable,key和Value都是String类型properties.load(fis); // 加载Java的配置文件classname.properties到内存中fis.close(); // 关闭输入流String classname = properties.getProperty("first"); // 通过key得到ValueClass<?> clazz = Class.forName(classname); // 获取classname(Value值)的类型Object obj = clazz.newInstance(); // 创建对象实例System.out.println(obj);}
}

因为这里的key传入的是first,所以输出为:

可以看出实例化了一个Object对象

还有另外一种方法,是比较常用简单的方法:
java.util包下提供了一个资源绑定器,便于获取属性配置文件中的内容;

需要使用该类的两个方法:

创建一个配置文件:

使用这种方式的时候,配置文件必须放到类路径(src)下

import java.util.ResourceBundle;// 使用以下这种方式的时候,属性配置文件xxx.properties必须放到类路径下。
// 实现和ReflectTest02一样的功能,但是又通过新的获取绝对路径的方法,而且以后常用这个方法
public class ReflectTest05 {public static void main(String[] args) throws Exception {// 资源绑定器,只能绑定xxx.properties文件。并且这个文件必须在类路径(src文件夹)下。文件扩展名也必须是properties// 并且在写路径的时候,路径后面的扩展名.properties不能写。ResourceBundle bundle = ResourceBundle.getBundle("absolute_path"); // 绑定配置文件String classname = bundle.getString("second"); // 通过key得到ValueClass c = Class.forName(classname);Object obj = c.newInstance();System.out.println(obj);}
}

这次key传入的是second,输出为:

反射机制的一些操作

下面展现反射机制的一些操作,其实就是各种方法的调用,会查文档就好;
这里先定义一个类,下面所有的操作都基于这个类;

public class TestClass01 {int age;public String name;private final static int num = 4;static protected boolean flag;public void firstMethod(String s) {System.out.println("第一个方法的调用!");}public void secondMethod(String s, int i) {System.out.println("第二个方法的调用!");}
}

反射TestClass类中所有Field(属性)

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;public class ReflectTest06 {public static void main(String[] args) throws Exception {// 获取整个类Class testClass = Class.forName("reflect.test06.TestClass01");// 获取类名String classname = testClass.getName(); // 完整类名System.out.println(classname);System.out.println(testClass.getSimpleName()); // 简单类名// 获取TestClass类的属性// getFields()只会获取所有public修饰的属性Field[] fields01 = testClass.getFields();Field f = fields01[0];String filename = f.getName(); // 获取属性名System.out.println(filename);System.out.println("=====================");// 获取所有属性Field[] fields02 = testClass.getDeclaredFields();for (Field i : fields02) {System.out.println(i.getName()); // 获取属性名// 获取属性的类型System.out.println(i.getType().getName()); // 完整类型System.out.println(i.getType().getSimpleName()); // 简单类型// 获取修饰符(用到了Modifier类的toString方法)System.out.println(Modifier.toString(i.getModifiers()));System.out.println("------------");}}
}

输出:

reflect.test06.TestClass01
TestClass01
name
=====================
age
int
int------------
name
java.lang.String
String
public
------------
num
int
int
private static final
------------
flag
boolean
boolean
protected static
------------

获取对象属性中的值

import java.lang.reflect.Field;public class ReflectTest07 {public static void main(String[] args) throws Exception {Class className = Class.forName("reflect.test06.TestClass01"); // 获取类Object obj = className.newInstance(); // 通过类创建对象Field ageFiled = className.getDeclaredField("age"); // 获取age属性// 给属性赋值需要有实例化的对象objageFiled.set(obj, 111); // 给obj对象的age属性复制111System.out.println(ageFiled.get(obj)); // 获取obj对象的age属性的值}
}

输出:

获取方法并调用(重要)

这个相对重要,获取方法用到了Class类的getMethod()方法或者getMethods()

返回类型Method:

同样获取方法后需要调用,使用Method类的一个方法:invoke()

下面是具体使用方法:

import java.lang.reflect.Method;// 通过反射机制调用方法
public class ReflectTest08 {public static void main(String[] args) throws Exception{// 先获取类Class c = Class.forName("reflect.test06.TestClass01");// 通过类实例化对象Object obj = c.newInstance();// 通过类获取方法Method method01 = c.getMethod("firstMethod", String.class);Method method02 = c.getMethod("secondMethod", String.class, int.class);// 通过获取的方法来调用(通过invoke方法)// 需要:1,该方法; 2,一个对象; 3,对应参数Object retValue01 = method01.invoke(obj, "这是一个没有什么用的参数");Object retValue02 = method02.invoke(obj, "这也是一个没有什么用的参数,后面1也是", 1);}
}

输出:

总结

这是反射机制一些基本常用操作,但是实际应用并不会这么简单,所以基础的一定要掌握好,这样在以后学习spring等框架时就能看懂学习底层源码了;
欢迎大家的点评!

[Java基础] 反射机制汇总相关推荐

  1. Java基础-反射机制

    目录 1.反射机制概述 2.获取class的三种方式 2.1.Class.forName()方式 2.2.obj.getClass()方式 2.3..class方式 3.通过反射实例化对象 4.通过读 ...

  2. 【java基础】java的反射机制

    1.简介 java的反射机制是java的特性之一,反射技术是构建框架技术的基础所在. java的反射机制,是指在运行状态中,对于任意一个类,都能知道这个类的所有属性和方法,对于任意一个对象,都能调用它 ...

  3. Java语言基础-反射机制、正则表达式

    反射机制 反射机制是在运行状态中,对于任意一个类,都能知道这个类(class文件)的所有属性和方法. 对于任意一个对象,都能调用它的任意一个方法和属性. 这种动态获取信息以及动态调用对象的方法的功能称 ...

  4. Java的反射机制 工厂模式综合讲解【转载自51CTO】

    2019独角兽企业重金招聘Python工程师标准>>> Java的反射机制 工厂模式综合讲解 1.什么叫反射 Java.lang.reflect包下 正常情况下我们可以通过类实例化一 ...

  5. 什么是Java的反射机制

    Java反射机制是Java的特点,是框架实现的基础,百度结果: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这 ...

  6. 什么是Java的反射机制?

    Java 的反射机制是使其具有动态特性的非常关键的一种机制,也是在JavaBean 中广泛应用的一种特性. 运用JavaBean 的最常见的问题是:根据指定的类名,类字段名和所对应的数据,得到该类的实 ...

  7. java中反射机制的含义_java的反射是什么意思?

    反射是Java的特征之一,是一种间接操作目标对象的机制. Java反射机制指的是在Java程序运行状态中,对于任何一个类,都可以获得这个类的所有属性和方法:对于给定的一个对象,都能够调用它的任意一个属 ...

  8. 16、Java 基础-反射

    Java 反射 1.反射 反射是指程序可以访问.检测.修改它本身的状态或行为的一种能力. 2.Java的反射机制 java的反射机制是指在程序的运行状态中,给定任意一个类,都可以获取到这个累的属性和方 ...

  9. Java的反射机制,内含超简单实例代码(搞懂反射,这一篇就够了)

    一 首先来说说反射机制的概念: 程序在运行时, 对于类来说,可以知道该类的任意属性和方法: 对于对象来说,可以调用该对象的任意方法和属性: 就以上这种动态获取信息的机制就称为Java的反射机制 彻底了 ...

最新文章

  1. 线段树3——一些例题的题解
  2. 深入理解分布式技术 - 降级和熔断
  3. gulp-babel 阻止了js文件编译的进程?
  4. hdu1018--Big Number
  5. Background-size完美兼容IE
  6. android 获取图片主色调
  7. LAMP架构mariadb/apache的安装及基本使用
  8. 一元运算符重载 前置和后置++ --(这种一般用成员函数来实现重载)
  9. idea代码补全_IDEA中有哪些让你相见恨晚的技巧?
  10. Atitit postgre sql json使用法 目录 1.1.1. 插入数据 1 2. json数据的常见操作 1 1.1.1.插入数据 插入数据可以直接以json格式插入: insert
  11. filenet骗局_将FileNet P8与J2EE消息传递基础结构集成
  12. 黑客帝国神级影评,转至豆瓣。 — — 哲思。
  13. P1757 通天之分组背包 (分组背包 模板
  14. 2022Java面试笔记(上)
  15. 转:通信十年:前辈对通信行业的分析与经历
  16. 决策树与R语言(RPART)
  17. ES6面试、复习干货知识点汇总
  18. 35搜索插入位置之Leecode—《数组篇》(二分法)
  19. CTFShow-电子取证篇Writeup
  20. gimbal lock 视频解释

热门文章

  1. 节点图一般的比例_基于图的异常检测(二):LOCKINFER
  2. 乐讯网python论坛_乐讯论坛
  3. 四核处理器_(技术文档)你知道AMD Ryzen处理器中的CCX与CCD是什么吗?
  4. android studio 执行不了,请问,Android studio程序不报错,但是一运行就stop是什原因...
  5. idea servlet自动配置web.xml_Spring Boot学习04_嵌入式Servlet容器自动配置原理
  6. 综合布线的12大热点技术
  7. AI:2020年6月22日北京智源大会演讲分享之10:40-11:10Daniel教授《 可微分的加权有限状态机及其机器学习应用》、11:10何晓冬教授《启动“智源-京东”任务导向多模态对话大赛》
  8. DL之BN-Inception:BN-Inception算法的简介(论文介绍)、架构详解、案例应用等配图集合之详细攻略
  9. TF学习——TF之Tensorboard:Tensorflow之Tensorboard可视化简介、入门、使用方法之详细攻略
  10. auto-sklearn手册