【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:/ ...
随机推荐
- Winpcap笔记3之打开适配器并捕获数据包
上一讲中知道了如何获取适配的信息,这一将我们讲写一个程序蒋每一个通过适配器的数据包打印出来. 打开设备的函数是pcap_open().函数原型是 pcap_t* pcap_open(const cha ...
- CodeForces 730G Car Repair Shop (暴力)
题意:给定 n 个工作的最好开始时间,和持续时间,现在有两种方法,第一种,如果当前的工作能够恰好在最好时间开始,那么就开始,第二种,如果不能,那么就从前找最小的时间点,来完成. 析:直接暴力,每次都先 ...
- vsftpd 配置文件
# mple config file /etc/vsftpd/vsftpd.conf # # The default compiled in settings are fairly paranoid. ...
- typedef struct和struct 的区别 用途
刚刚想到的,我们在用结构体的时候会遇到'->'和'.',这是什么情况呢? 不能混用的(c和c++不同语言对它们没有影响) 我说的不能混用的意思是'.'用于结构体指针的指向......而'-& ...
- Unix\Linux | 总结笔记 | man帮助
0.目录 手册页分类说明 man手册中的段落说明 1. man手册页分类 man1 普通用户可以执行的命令帮助 man2 系统调用.内核函数的说明帮助 man3 库函数说明帮助 ma ...
- ambari-server启动WARN qtp-ambari-client-87] ServletHandler: 563 /api/v1/stacks/HDP/versions/2.4/recommendations java.lang.NullPointerException报错解决办法(图文详解)
问题详情 来源是,我在Ambari集群里,安装Hue. 给Ambari集群里安装可视化分析利器工具Hue步骤(图文详解 所遇到的这个问题. 然后,去ambari-server的log日志,查看,如 ...
- 平板&Safari 开发tips
css: *{ margin: 0; padding: 0; /* 禁止用户点选网页内容 */ -webkit-touch-callout:none; -webkit-user-select:non ...
- css3 transform + deviceorientation实现图片旋转效果
1. 陀螺仪deviceorientation的使用,参考<关于陀螺仪deviceorientation>https://segmentfault.com/a/11900000071838 ...
- vim插件minibuf配置
1.去下载网站下载minibufexpl.vim文件放入到~/vim/plugins中,有的系统路径是~/.vim/plugins; 下载网址如下 https://www.vim.org/script ...
- git---安装及配置
git官网:https://git-scm.com 安装: 官网下载->一路Next->安装完成 配置git: 1.win+r进入windows命令行 2.注册: git config - ...