通过程序化的方式间接对Class的对象实例操作,Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数、属性和方法等。
Java允许用户借由这个Class相关的元信息对象间接调用Class对象的功能,则就为使用程序化方法操作Class对象开辟了途径。
 
类装载器 ClassLoader
类装载器就是寻找类的字节码文件并构造出类在JVM内部表示的对象组件。在Java中,类装载器把一个类装入JVM中,经过的步骤如下:
1)装载:查找和导入Class文件;
2)链接:执行校验、准备和解析步骤,其中解析步骤是可以选择的:
    a)校验:检查载入Class文件数据的正确性;
    b)准备:给类的静态变量分配存储空间;
    c)解析:将符号引用转成直接引用;
3)初始化:对类的静态变量、静态代码块执行初始化工作。
JVM在运行时会产生三个ClassLoader:根装载器、ExtClassLoader(扩展类装载器)和AppClassLoader(系统类装载器)。
package com.reflect;
/**
* Created by gao on 16-3-18.
*/
public class ClassLoaderTest {
public static void main(String[] args) {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
System.out.println("current loader:" + loader);
System.out.println("parent loader:" + loader.getParent());
System.out.println("grandparent loader:" + loader.getParent().getParent());
}
}

输出结果:

current loader:sun.misc.Launcher$AppClassLoader@6ba5d6d6
parent loader:sun.misc.Launcher$ExtClassLoader@54bbb2d0
grandparent loader:null
 
ClassLoader重要方法:
1)Class loaderClass(String name):name参数指定类装载器需要装载类的名字,必须使用全限类名。该方法有一个重载方法loadClass(String name, boolean resolve),resolve参数告诉类装载器是否需要解析该类。
2)Class defineClass(String name, byte[] b, int off, int len):将类文件的字节数组转换成JVM内部的java.lang.Class对象。
3)Class findSystemClass(String name):从本地文件系统载入Class文件。
4)Class findLoadedClass(String name):调用该方法来查看ClassLoader是否已装入某个类。
5)ClassLoader getParent():获取类装载器的父装载器。
 
Java反射机制:
Class反射对象描述类语义结构,可以从Class对象中获取构造函数、成员变量、方法类等类元素的反射对象,并以编程的方式通过这些反射对象对目标类对象进行操作。
1)Constructor:类的构造函数反射类,通过Class#getConstructors()方法可以获得类的所有构造函数反射数组。还可以通过getConstructor(Class...parameterTypes)获取拥有特定入参的构造函数对象。Constructor的一个主要方法是newinstance(Object[] initargs),通过该方法可以创建一个对象类的实例,相当于new关键字。
2)Method:类方法的反射类,通过Class#getDeclaredMethods()方法可以获取类的所有方法反射类对象数组Method[]。在JDK5中可以通过getDeclaredMethod(String name, Class...parameterTypes)获取特定签名的方法。Method最主要的方法是invoke(Object obj, Object[] args)。
    a)Class getReturnType():获取方法的入参类型数组;
    b)Class[] getParameterTypes():获取方法的入参类型数组;
    c)Class[] getExecptionTypes():获取方法的异常类型数组;
    d)Annotation[][] getParameterAnnotations():获取方法的注解信息
3)Field:类的成员变量的反射类,通过Class#getDeclaredFields()方法可以获取类的成员变量反射对象数组,通过Class#getDeclaredField(String name)则可获取某个特定名称的成员变量反射对象。Field类最主要的方法是set(Object obj,Object value)。
 
1、构建一个简单的Web项目:chapter03
 
 
2、创建类com.reflect.Car
package com.reflect;
/**
* Created by gao on 16-3-18.
*/
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 String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getMaxSpeed() {
return maxSpeed;
}
public void setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
}
public void introduce() {
System.out.println("brand:" + brand + ";color:" + color + ";maxSpeed:" + maxSpeed);
}
protected void drive(){
System.out.println("dirve private car! the color is:"+color);
}
}

3、创建测试类com.reflect.ReflectTest

package com.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* Created by gao on 16-3-18.
*/
public class ReflectTest {
public static Car initByDefaultConst() throws Throwable{
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class clazz = loader.loadClass("com.reflect.Car");
Constructor cons = clazz.getDeclaredConstructor((Class[]) null);
Car car = (Car)cons.newInstance();
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,300);
return car;
}
public static void main(String[] args) throws Throwable {
Car car = initByDefaultConst();
car.introduce();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class clazz = loader.loadClass("com.reflect.Car");
Car car1 = (Car)clazz.newInstance();
Field colorFld = clazz.getDeclaredField("color");
colorFld.setAccessible(true);
colorFld.set(car1, "白色");
Method dirveMtd = clazz.getDeclaredMethod("drive",(Class[])null);
dirveMtd.setAccessible(true);
dirveMtd.invoke(car1,(Object[])null);
}
}
结果输出:
brand:奥迪;color:红色;maxSpeed:300
dirve private car! the color is:白色
 
 
 
 
 
 
 

Java—反射的更多相关文章

  1. 第28章 java反射机制

    java反射机制 1.类加载机制 1.1.jvm和类 运行Java程序:java 带有main方法的类名 之后java会启动jvm,并加载字节码(字节码就是一个类在内存空间的状态) 当调用java命令 ...

  2. Java反射机制

    Java反射机制 一:什么事反射机制 简单地说,就是程序运行时能够通过反射的到类的所有信息,只需要获得类名,方法名,属性名. 二:为什么要用反射:     静态编译:在编译时确定类型,绑定对象,即通过 ...

  3. java反射(基础了解)

    package cn.itcast_01; /** *Person类 */ public class Person {    /** 姓名 */    private String name;     ...

  4. java基础知识(十一)java反射机制(上)

    java.lang.Class类详解 java Class类详解 一.class类 Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时 ...

  5. java基础知识(十一)java反射机制(下)

    1.什么是反射机制? java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象都能够调用他的属性和方法,这种动态获取属性和方法的功能称为java的反射机制. ...

  6. java反射学习之二万能EXCEL导出

    一.EXCEL导出的实现过程 假设有一个对象的集合,现在需要将此集合内的所有对象导出到EXCEL中,对象有N个属性:那么我们实现的方式是这样的: 循环这个集合,在循环集合中某个对象的所有属性,将这个对 ...

  7. java反射学习之一反射机制概述

    一.反射机制背景概述 1.反射(reflection)是java被视为动态语言的一个关键性质 2.反射机制指的是程序在运行时能获取任何类的内部所有信息 二.反射机制实现功能概述 1.只要给定类的全名, ...

  8. java反射 之 反射基础

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

  9. java反射 cglib asm相关资料

    有篇文章对java反射的调用的效率做了测试,写的比较好.猛击下面地址 http://www.blogjava.net/stone2083/archive/2010/09/15/332065.html ...

  10. 超详细的java反射教程

    看技术博客时,看到关于java反射的博文,写的非常好.猛击下面的地址,开始java反射之旅 中文翻译地址:http://ifeve.com/java-reflection/ 英文原版地址:http:/ ...

随机推荐

  1. Android Studio笔记(2)——快捷键

    在朋友推荐下,上个星期黄老师我用上了Google的新黑暗工具,基于Intellij idea的新Android开发集成开发环境 ——Android Studio,用下来感觉还算不错,但作为一个ADT ...

  2. Oracle之存储过程

    1.存储过程创建 oracle中创建存储过程的语法如下: CREATE [OR REPLACE] PROCEDURE PRO_NAME[(parameter1[,parameter2]...)]is| ...

  3. nullptr和NULL

    nullptr是c++11中的关键字,表示空指针 要区分nullptr和NULL,首先要明白NULL的含义: NULL是一个宏定义,在c和c++中的定义不同,c中NULL为(void*)0,而c++中 ...

  4. cocos2dx中的背景图层CCLayerColor和渐变图层CCLayerGradient

    1.CCLayerColor是专门用来处理背景颜色的图层,它继承自CCLayer,可以用来设置图层的背景颜色,因为CCLayer默认是透明色的,即无颜色的 2.CCLayerGradient是用来显示 ...

  5. 在唯一密钥属性“value”设置为“Default.aspx”时,无法添加类型为“add”的重复集合项

    环境:windows server 2012  asp.net 找到网站目录:wwwroot ,打开web.config文件,在 在<files>与</files>之间加入代码 ...

  6. android 开发,多个线程共用一个handler

    在做项目过程中,突然发现,项目中启动了多个线程,但是只有一个handler,而不需要每一个线程单独开一个handler,记下笔记: handler = new Handler() { @Overrid ...

  7. CSS:在input、pre中左边加上一个图标(一行和多行)

    前言 接触过EasyUI的朋友都知道其警告框就是左边有个三角警告图标,此文所做的效果正是这样.此外,还将示例多行的做法. 一.在input左边加上一个图标(一行) 注:left center定义了图标 ...

  8. WEB前端常用的测试工具

    一.QUnit 前端测试工具 QUnit是一个强大的JavaScript单元测试框架,该框架是由jQuery团队的成员所开发,并且是jQuery的官方测试套件.Qunit是Jquery的单元测试框架, ...

  9. 【转】欧拉回路&特殊图下的哈密顿回路题集

    转自:http://blog.csdn.net/shahdza/article/details/7779385 欧拉回路[HDU]1878 欧拉回路 判断3018 Ant Trip 一笔画问题1116 ...

  10. C#常用简单线程实例

    using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...