java 反射 类装载器
前言:
java语言允许通过程序化的方式间接对Class进行操作,Class文件由类装载器装载后,在jvm中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息,如构造函数,属性和方法等,
java允许用户借由这个与Class相关的元信息对象间接调用Class对象的功能,这就为使用程序化方式操作Class对象开辟了途径。
实例:
下面一个Car类拥有两个构造函数,一个方法及三个属性
package reflect; public class Car {
private String brand; //品牌
private String color; //颜色
private int maxSpeed; //转速 public Car(){} public Car(String brand, String color, int maxSpeed){
this.brand = brand;
this.color = color;
this.maxSpeed = maxSpeed;
}
public void say(){
System.out.println("brand:"+ brand + ", color:"+ color +", maxSpeed:"+ maxSpeed);
} //set和get 方法省略
一般情况下,我们会使用如下代码创建Car的实例:
Car car = new Car();
car.setBrand("红旗");
这种是采用传统方式直接调用目标类,下面我们可以使用java反射机制以一种间接的方式操控目标类:
public class ReflectTest { public static Car initByDefaultConst() throws Throwable{
// 1. 通过类装载器获取Car类的对象
ClassLoader loader = Thread.currentThread().getContextClassLoader();
//使用全限定名来找class类
Class clazz = loader.loadClass("reflect.Car"); /*Class clazz = Class.forName("reflect.Car");*/ //另一种方式获取class // 2. 获取类的默认构造器对象并通过它实例化Car
Constructor cons = clazz.getDeclaredConstructor((Class[])null);
Car car = (Car)cons.newInstance(); // 3. 通过反射方法设置属性
Method setBrand = clazz.getMethod("setBrand", String.class);
setBrand.invoke(car,"红旗");
Method setColor = clazz.getMethod("setColor", String.class);
setColor.invoke(car,"黑色");
Method setMaxSpeed = clazz.getMethod("setMaxSpeed", int.class);
setMaxSpeed.invoke(car,200);
return car;
}
@Test
public void test() throws Throwable{
Car car = initByDefaultConst();
car.say();
}
}
运行以上程序,在控制台打印如下: brand:红旗, color:黑色, maxSpeed:200
上述的程序只是用了很少的api,java反射包为我们提供了很多的方法,可以细查。
其余扩展:
类装载器ClassLoader的工作机制:
类装载器就是寻找类的节码文件并构造出类在jvm内部表示对象的组件,在java中,类装载器把一个类装入jvm中,需要经过如下步骤:
1. 装载:查找和导入Class文件
2. 链接:执行校验,准备和解析步骤,其中解析步骤是可以选择的
2.1. 校验:检查载入Class文件数据的正确性
2.2. 准备: 给类的静态变量分配存储空间
2.3. 解析:将符号引用转换成直接引用
3. 初始化:对类的静态变量,静态代码块执行初始化工作
JVM装载类使用 “全盘负责委托机制”,
“全盘负责”是指当一个ClassLoader装载一个类时(除非显式的使用另一个ClassLoader),该类所依赖及引用的类也由这个ClassLoader载入;
“委托机制”是指先委托父装载器寻找目标类,只有在找不到的情况下才从自己的类路径中查找并装载目标类。
这一点是从安全角度考虑的,试想,如果有一个人编写了一个恶意的基础类(如java.lang.String)并装载到JVM中,将会引起多么可怕的后果,
但是由于有了“全盘负责委托机制”,java.lang.String永远是根装载器来装载的,这样就避免了上述安全隐患的发生。
java 反射 类装载器的更多相关文章
- java 反射的应用 以及通过反射 用到的工厂模式
java反射详解 本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案 ...
- Java反射机制详解
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反 ...
- Java—反射
通过程序化的方式间接对Class的对象实例操作,Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数.属性和方法 ...
- java 反射(reflect)总结,附对象打印工具类
java反射机制认知 java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取类的信息以及动态调用对象的方法的 ...
- java反射机制简单实例
目录 Java反射 简单实例 @(目录) Java反射 Java语言允许通过程序化的方式间接对Class进行操作.Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通 ...
- 【java】-- java反射机制
参考文章:https://blog.csdn.net/sinat_38259539/article/details/71799078 https://blog.csdn.net/wanderlu ...
- 【java基础】Java反射机制
一.预先需要掌握的知识(java虚拟机) 1)java虚拟机的方法区: java虚拟机有一个运行时数据区,这个数据区又被分为方法区,堆区和栈区,我们这里需要了解的主要是方法区.方法区的主要作用是存 ...
- Java反射拾遗
定义:Java反射机制可以让我们在编译期(Compile Time)之外的运行期(Runtime)检查类,接口,变量以及方法的信息.反射还可以让我们在运行期实例化对象,调用方法,通过调用get/set ...
- java反射机制与动态代理
在学习HadoopRPC时.用到了函数调用.函数调用都是採用的java的反射机制和动态代理来实现的,所以如今回想下java的反射和动态代理的相关知识. 一.反射 JAVA反射机制定义: JAVA反射机 ...
随机推荐
- SQL分组查询
把数据分成多个逻辑组,以便能对每个组的数据进行操作,对每个组进行聚集计算. 1.创建分组 分组是在SELECT语句的GROUP BY子句中建立的 例子: SELECT vendId ...
- C/C++资料网站
1.C语言基础知识讲解 http://c-faq-chn.sourceforge.net/ccfaq/node1.html 2.C++参考手册中文版 http://zh.cppreference.co ...
- webstom破解
链接:http://pan.baidu.com/s/1dFOpj1n 密码:rsfs
- NAT集群部署solo之session server
author:JevonWei 版权声明:原创作品 使用Nginx做代理服务器,部署solo,使用session server做会话黏滞 拓扑图 环境 tomcatA 172.16.253.108 t ...
- 使用反射+策略模式代替项目中大量的switch case判断
我这里的业务场景是根据消息类型将离线消息存入mongoDB不同的collection中.其中就涉及到大量的分支判断,为了增强代码的可读性和可维护性,对之前的代码进行了重构. 先对比一下使用反射+策略模 ...
- PropertiesUtil demo
package com.spl.save.wmos.base.util; import java.io.File; import java.io.FileInputStream; import jav ...
- Swift_语法的熟悉
Swift_语法的熟悉 oc与swift区变 文件区别oc有实现文件以及声明文件等,在swift中实现机声明类似文件总归结一个即可 1. 常量与变量的初始化 常量 关键字"let" ...
- 解决:"不再sudoers文件中,此事将不做被报告”的问题
使用sudo出现问题:不再sudoers文件中,此事将不做被报告 系统:win8.1 +cents 7 问题:在虚拟机中,默认不是root账号,在使用sudo命令时候收到下面警告: sudo命令含义: ...
- Spring Boot + Dubbo 可运行的例子源码-实现服务注册和远程调用
最近公司的一个分布式系统想要尝试迁移到Dubbo,项目本身是Spring Boot的,经过一些努力,最终也算是搭建起一个基础的框架了,放到这里记录一下.需要依赖一个外部的zookeeper. 源码地址 ...
- 九度OJ 1016 火星A+B AC版
#include <iostream> #include <string.h> #include <sstream> #include <math.h> ...