【thinking in java】反射
前言
反射是框架设计的灵魂,使用的前提条件:必须先得到字节码的Class,Class类用于表示字节码,字节码即是.class文件
概述
JAVA反射机制:在程序运行的过程中,对于任意一个类,都可以知道这个类的所有信息,比如:成员变量、方法、构造方法、包等信息;要想用反射机制,首先要获取到
该类的字节码文件对象Class,然后用Class类中的方法把各种成分映射成Java对象,关于.class文件,在我们new对象的时候,本地IDE自动编译,然后jvm会自动的从硬盘
读取到.class文件,并创建一个该类的Class文件,但是,如果我们new了多个该类的实例,内存中只会有一份该类的字节码文件。
API
Class 类与 java.lang.reflect 类库一起对反射的概念进行了支持,该类库包含了 Field、Method、Constructor 类 (每个类都实现了 Member 接口)该接口反映单个成员
(字段或方法)或构造方法的标识信息,正因为实现了该接口,因此可以反射相关变量、方法信息,这些类型的对象时由 JVM 在运行时创建的,用以表示未知类里对应的成员
反射
获取字节码
在 Java 中可以通过三种方法获取类的字节码 (Class) 对象,如下:
package com.oxygen.bean; public class ReflectTest {
public static void main(String[] args) throws ClassNotFoundException {
Student student = new Student();
Class<?> clazz1 = student.getClass(); //方式1
Class<?> clazz2 = Student.class; //方式2
Class clazz3 = Class.forName("com.oxygen.student");//方式3
}
}
获取类信息
Student类如下
package com.oxygen.bean; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; public class Student {
private String name;
private Integer age;
private Car car; public void init() {
System.out.println("init...");
} public void destroy() {
System.out.println("destroy...");
} public Student() { // 无参构造
} public Student(String name, Integer age, Car car) {
super();
this.name = name;
this.age = age;
this.car = car;
} private Student(String name) {
this.name = name;
} public void show1(String s) {
System.out.println("调用了:公有的,String参数的show1(): name = " + s);
} protected void show2() {
System.out.println("调用了:受保护的,无参的show2()");
} void show3() {
System.out.println("调用了:默认的,无参的show3()");
} private String show4(int age) {
System.out.println("调用了,私有的,并且有返回值的,int参数的show4(): age = " + age);
return "oxygen";
}
}
1. 通过构造函数对象Constructor创建对应类的实例
package com.oxygen.bean; import java.lang.reflect.Constructor; public class ReflectTest {
public static void main(String[] args) throws Exception {
Student student = new Student(); //Student的带参构造函数依赖另外一个类Car
Class<?> clazz1 = student.getClass(); //方式1
func1(clazz1); //通过无参构造函数反射Student实例
func2(clazz1);//通过有参构造函数反射Student实例
func3(clazz1);//获取所有的构造函数反射Student实例
func4(clazz1); // 反射私有构造函数
} private static void func4(Class<?> clazz1) throws Exception {
Constructor<?> declaredConstructor = clazz1.getDeclaredConstructor(String.class);
declaredConstructor.setAccessible(true);//设置为可以访问
System.out.println(declaredConstructor.newInstance("zhangsan"));
} private static void func3(Class<?> clazz1) throws Exception {
Constructor<?>[] constructors = clazz1.getDeclaredConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println("func3: " + constructor);
}
} /**
* 因为Student的带参构造函数依赖另外一个类Car,因为必须保证JVM能获取到Car的字节码
* @param clazz1
* @throws Exception
*/
public static void func2(Class<?> clazz1) throws Exception {
Car car = new Car();//保证
Constructor<?> constructor = clazz1.getConstructor(String.class, Integer.class, Car.class);
Student student = (Student) constructor.newInstance("张三", 18, new Car());
System.out.println(student);
} public static void func1(Class<?> clazz1) throws Exception {
Constructor<?> constructor = clazz1.getConstructor();
Student student = (Student) constructor.newInstance();
System.out.println(student);
}
}
2. 获取成员方法
package com.oxygen.bean; import java.lang.reflect.Constructor;
import java.lang.reflect.Method; public class ReflectTest {
public static void main(String[] args) throws Exception {
Student student = new Student();
Class<?> clazz1 = student.getClass();
m1(clazz1);
m2(clazz1);
m3(clazz1);
m4(clazz1);
} /**
* 获取所有的方法,包括私有的,不包括继承Object类的9个方法
* @param clazz1
*/
public static void m4(Class<?> clazz1) {
Method[] declaredMethods = clazz1.getDeclaredMethods();
} /**
* 获取所有的”公有“方法,包括继承Object类的9个方法
* @param clazz1
*/
public static void m3(Class<?> clazz1) {
Method[] methods = clazz1.getMethods();
} /**
* 获取私有的show4()方法
* @param clazz1
* @throws Exception
*/
public static void m2(Class<?> clazz1) throws Exception {
Method method;
method = clazz1.getDeclaredMethod("show4", int.class);
Student stu = func1(clazz1); // 实例化一个Student对象
method.setAccessible(true);
method.invoke(stu, 20);//反射私有方法show4(),第一个参数是实例,第二个参数是被反射方法的参数
} /**
* 获取公有的show1()方法
* @param clazz1
* @throws Exception
*/
public static void m1(Class<?> clazz1) throws Exception {
Method method = clazz1.getMethod("show1", String.class); //第一个参数是方法名称,第二个参数是形参类型
Student stu = func1(clazz1); // 实例化一个Student对象
method.invoke(stu, "lisi"); //反射公有方法show1(),第一个参数是实例,第二个参数是被反射方法的参数
} public static Student func1(Class<?> clazz1) throws Exception {
Constructor<?> constructor = clazz1.getConstructor();
Student student = (Student) constructor.newInstance();
return student;
}
}
【thinking in java】反射的更多相关文章
- 第28章 java反射机制
java反射机制 1.类加载机制 1.1.jvm和类 运行Java程序:java 带有main方法的类名 之后java会启动jvm,并加载字节码(字节码就是一个类在内存空间的状态) 当调用java命令 ...
- Java反射机制
Java反射机制 一:什么事反射机制 简单地说,就是程序运行时能够通过反射的到类的所有信息,只需要获得类名,方法名,属性名. 二:为什么要用反射: 静态编译:在编译时确定类型,绑定对象,即通过 ...
- java反射(基础了解)
package cn.itcast_01; /** *Person类 */ public class Person { /** 姓名 */ private String name; ...
- java基础知识(十一)java反射机制(上)
java.lang.Class类详解 java Class类详解 一.class类 Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时 ...
- java基础知识(十一)java反射机制(下)
1.什么是反射机制? java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象都能够调用他的属性和方法,这种动态获取属性和方法的功能称为java的反射机制. ...
- java反射学习之二万能EXCEL导出
一.EXCEL导出的实现过程 假设有一个对象的集合,现在需要将此集合内的所有对象导出到EXCEL中,对象有N个属性:那么我们实现的方式是这样的: 循环这个集合,在循环集合中某个对象的所有属性,将这个对 ...
- java反射学习之一反射机制概述
一.反射机制背景概述 1.反射(reflection)是java被视为动态语言的一个关键性质 2.反射机制指的是程序在运行时能获取任何类的内部所有信息 二.反射机制实现功能概述 1.只要给定类的全名, ...
- java反射 之 反射基础
一.反射 反射:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为 ...
- java反射 cglib asm相关资料
有篇文章对java反射的调用的效率做了测试,写的比较好.猛击下面地址 http://www.blogjava.net/stone2083/archive/2010/09/15/332065.html ...
- 超详细的java反射教程
看技术博客时,看到关于java反射的博文,写的非常好.猛击下面的地址,开始java反射之旅 中文翻译地址:http://ifeve.com/java-reflection/ 英文原版地址:http:/ ...
随机推荐
- 通过爬虫爬取四川省公共资源交易平台上最近的招标信息 --- URLConnection
通过爬虫爬取公共资源交易平台(四川省)最近的招标信息 一:引入JSON的相关的依赖 <dependency> <groupId>net.sf.json-lib< ...
- NOIp 2014 寻找道路【图的遍历/最短路】By cellur925
题目传送门 比较裸的图论,结果自己还是没做出来,我真菜. 我们根据题意,只要把不能通向终点的点求出,然后再分别以这些点为起点,求出它们能到达的点,这些点也不能在路径上. 之后跑一个最短路即可. 注意以 ...
- js实现打字效果
<!DOCTYPE html> <html> <head> <meta charset='utf-8'> <title>js typing& ...
- 字体使用sp、dp的区别
Android设置字体大小, 该用sp还是dp? 大部分人肯定脱口而出, 用sp啊, 傻瓜都知道要用sp而不是dp!!! 那么为什么呢? 可能有人会说, 是google官方专门定义了sp这个单位来描述 ...
- Codeforces Round #479 (Div. 3)解题代码
A. Wrong Subtraction #include <bits/stdc++.h> using namespace std; int main() { int n,k; cin&g ...
- iOS9导入高德地图报错App Transport Security has blocked...
App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Te ...
- 419 Battleships in a Board 甲板上的战舰
给定一个二维的甲板, 请计算其中有多少艘战舰. 战舰用 'X'表示,空位用 '.'表示. 你需要遵守以下规则: 给你一个有效的甲板,仅由战舰或者空位组成. 战舰只能水平或者垂直放置.换句话 ...
- Solr中的group与facet的区别 [转]
Solr中的group与facet的区别 facet 自己理解就是分组聚合用的, 如下说明 http://blog.csdn.net/a925907195/article/details/472572 ...
- [转][ASP.NET MVC]如何定制Numeric属性/字段验证消息
本文转自:http://www.cnblogs.com/artech/archive/2012/02/13/NumericPropertyValidation.html 对于一个Numeric属性/字 ...
- AJPFX总结Java 类与对象的初始化
面试的时候,经常会遇到这样的笔试题:给你两个类的代码,它们之间是继承的关系,每个类里只有构造器方法和静态块,它们只包含一些简单的输出字符串到控制台的代码,然后让我们写出正确的输出结果.这实际上是在考察 ...