前言:

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 反射 类装载器的更多相关文章

  1. java 反射的应用 以及通过反射 用到的工厂模式

    java反射详解 本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案 ...

  2. Java反射机制详解

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

  3. Java—反射

    通过程序化的方式间接对Class的对象实例操作,Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数.属性和方法 ...

  4. java 反射(reflect)总结,附对象打印工具类

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

  5. java反射机制简单实例

    目录 Java反射 简单实例 @(目录) Java反射 Java语言允许通过程序化的方式间接对Class进行操作.Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通 ...

  6. 【java】-- java反射机制

    参考文章:https://blog.csdn.net/sinat_38259539/article/details/71799078    https://blog.csdn.net/wanderlu ...

  7. 【java基础】Java反射机制

    一.预先需要掌握的知识(java虚拟机)  1)java虚拟机的方法区:  java虚拟机有一个运行时数据区,这个数据区又被分为方法区,堆区和栈区,我们这里需要了解的主要是方法区.方法区的主要作用是存 ...

  8. Java反射拾遗

    定义:Java反射机制可以让我们在编译期(Compile Time)之外的运行期(Runtime)检查类,接口,变量以及方法的信息.反射还可以让我们在运行期实例化对象,调用方法,通过调用get/set ...

  9. java反射机制与动态代理

    在学习HadoopRPC时.用到了函数调用.函数调用都是採用的java的反射机制和动态代理来实现的,所以如今回想下java的反射和动态代理的相关知识. 一.反射 JAVA反射机制定义: JAVA反射机 ...

随机推荐

  1. SQL分组查询

      把数据分成多个逻辑组,以便能对每个组的数据进行操作,对每个组进行聚集计算. 1.创建分组 分组是在SELECT语句的GROUP BY子句中建立的 例子:         SELECT vendId ...

  2. C/C++资料网站

    1.C语言基础知识讲解 http://c-faq-chn.sourceforge.net/ccfaq/node1.html 2.C++参考手册中文版 http://zh.cppreference.co ...

  3. webstom破解

    链接:http://pan.baidu.com/s/1dFOpj1n 密码:rsfs

  4. NAT集群部署solo之session server

    author:JevonWei 版权声明:原创作品 使用Nginx做代理服务器,部署solo,使用session server做会话黏滞 拓扑图 环境 tomcatA 172.16.253.108 t ...

  5. 使用反射+策略模式代替项目中大量的switch case判断

    我这里的业务场景是根据消息类型将离线消息存入mongoDB不同的collection中.其中就涉及到大量的分支判断,为了增强代码的可读性和可维护性,对之前的代码进行了重构. 先对比一下使用反射+策略模 ...

  6. PropertiesUtil demo

    package com.spl.save.wmos.base.util; import java.io.File; import java.io.FileInputStream; import jav ...

  7. Swift_语法的熟悉

    Swift_语法的熟悉 oc与swift区变 文件区别oc有实现文件以及声明文件等,在swift中实现机声明类似文件总归结一个即可 1. 常量与变量的初始化 常量 关键字"let" ...

  8. 解决:"不再sudoers文件中,此事将不做被报告”的问题

    使用sudo出现问题:不再sudoers文件中,此事将不做被报告 系统:win8.1 +cents 7 问题:在虚拟机中,默认不是root账号,在使用sudo命令时候收到下面警告: sudo命令含义: ...

  9. Spring Boot + Dubbo 可运行的例子源码-实现服务注册和远程调用

    最近公司的一个分布式系统想要尝试迁移到Dubbo,项目本身是Spring Boot的,经过一些努力,最终也算是搭建起一个基础的框架了,放到这里记录一下.需要依赖一个外部的zookeeper. 源码地址 ...

  10. 九度OJ 1016 火星A+B AC版

    #include <iostream> #include <string.h> #include <sstream> #include <math.h> ...