反射的作用:
 
1.运行时检查类的结构
2.运行时更改类的字段值
3.调用类的方法
 
准备知识:
 
Class类:虚拟机为每一个对象保存的一份对象所属类的清单:
static Class forName(String className) 获取字符串(接口或者类的全类名)对应的类的Class对象。
Object newInstance() 返回Class对应的类的一个对象
 
解析: 
1.运行时检查类的结构
    java.lang.reflection 中有三个类:
    1.Field 对应类的字段
        getName() 返回Field对应的名称
        getType() 返回Field所在的Class类型
    2.Method 对应类的方法
        getName() 返回Method 对应的名称
        Class<?>[] getParameterTypes() 按方法声明的顺序返回参数类型数组
        int getModifiers() 返回一个整数值,用不同的位开关表示static,public这样的修饰情况。
    3.Constructor 对应构造器
        getName() 返回Constructor 对应的名称
        Class<?>[] getParameterTypes() 按方法声明的顺序返回参数类型数组
        int getModifiers() 返回一个整数值,用不同的位开关表示static,public这样的修饰情况。
 
在Method和Constructor中可以使用Modifier类的isPrivate,isStatic 来判断getModifiers()的返回值,给出是否含有对应的修饰符。
Class对象的getDeclaredConstructors,getDeclaredMethods,getDeclaredFields分别用于获取对象的构造器,方法,字段,以数组的形式返回。
 
下面为反射基本用法:检测一个类的结构:
 
 import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier; //反射基本测试
public class ReflectionTest {
public static void main(String[] args) {
String name = "java.util.Date";
try {
Class cl = Class.forName(name);
Class supercl = cl.getSuperclass();
String modifiers = Modifier.toString(cl.getModifiers());
if (modifiers.length() > 0) System.out.print(modifiers + " ");
System.out.print("class " + name);
if (supercl != null && supercl != Object.class) System.out.print(" extends "
+ supercl.getName()); System.out.print("\n{\n");
printConstructors(cl);
System.out.println();
printMethods(cl);
System.out.println();
printFields(cl);
System.out.println("}");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.exit(0);
} public static void printConstructors(Class cl) {
Constructor[] constructors = cl.getDeclaredConstructors(); for (Constructor c : constructors) {
String name = c.getName();
System.out.print(" ");
String modifiers = Modifier.toString(c.getModifiers());
if (modifiers.length() > 0) System.out.print(modifiers + " ");
System.out.print(name + "("); // print parameter types
Class[] paramTypes = c.getParameterTypes();
for (int j = 0; j < paramTypes.length; j++) {
if (j > 0) System.out.print(", ");
System.out.print(paramTypes[j].getName());
}
System.out.println(");");
}
} public static void printMethods(Class cl) {
Method[] methods = cl.getDeclaredMethods(); for (Method m : methods) { Class retType = m.getReturnType();
String name = m.getName(); System.out.print(" ");
// print modifiers, return type and method name
String modifiers = Modifier.toString(m.getModifiers());
if (modifiers.length() > 0) System.out.print(modifiers + " ");
System.out.print(retType.getName() + " " + name + "("); // print parameter types
Class[] paramTypes = m.getParameterTypes();
for (int j = 0; j < paramTypes.length; j++) {
if (j > 0) System.out.print(", ");
System.out.print(paramTypes[j].getName());
}
System.out.println(");");
}
} public static void printFields(Class cl) {
Field[] fields = cl.getDeclaredFields(); for (Field f : fields) {
Class type = f.getType();
String name = f.getName();
System.out.print(" ");
String modifiers = Modifier.toString(f.getModifiers());
if (modifiers.length() > 0) System.out.print(modifiers + " ");
System.out.println(type.getName() + " " + name + ";");
}
}
}
2.更改类的字段值:
    Field对象有以下对应的一系列方法:
    public Object get(Object obj) 获取目标对象上字段的值
    public void set(Object obj, Object value)设置目标对象上字段的值
    有相应具体类型的get和set方法。
 
3.调用类的方法(类似于方法指针):
    Method对象方法:
     public Object invoke(Object obj, Object... args)
    obj是调用的目标对象,ars是方法参数
 
以下为示例代码:
 import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; /**
* Created by karlx on 2015/5/29.
*/
public class ReflectionTest2 {
public static void main(String[] args) {
Person person = new Person();
person.name = "karl";
//获取,设置 运行中对象的字段值
Class clazz = person.getClass();
try {
Field field = clazz.getField("name");
field.setAccessible(true);//避开java的访问检查
System.out.println(field.get(person)); field.set(person, "xiaoming");
System.out.println(field.get(person)); } catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
//运行中调用对象的方法
try {
Method method = clazz.getMethod("getName");
method.setAccessible(true);//避开java的访问检查
System.out.println(method.invoke(person));
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
} static class Person {
public String name; public String getName() {
return name + "hello";
} public void setName(String name) {
this.name = name;
}
}
}

Java反射的理解的更多相关文章

  1. Java反射的理解(六)-- 通过反射了解集合泛型的本质

    Java反射的理解(六)-- 通过反射了解集合泛型的本质 上述写了那么多,我们可能会有个疑问,为什么要用反射,步骤比我们常规的加载类操作复杂多了,别急,这个问题我最后才解答,我们先来了解集合泛型的本质 ...

  2. (转)JAVA反射机制理解

    JAVA反射机制: 通俗地说,反射机制就是可以把一个类,类的成员(函数,属性),当成一个对象来操作,希望读者能理解,也就是说,类,类的成员,我们在运行的时候还可以动态地去操作他们. 理论的东东太多也没 ...

  3. java反射的理解与应用(某大神博客中看到的博文,写的真的太好了,果断转载作为笔记)

    原文地址:http://www.cnblogs.com/jqyp/archive/2012/03/29/2423112.html#undefined 一.什么是反射机制 简单的来说,反射机制指的是程序 ...

  4. Java 反射的理解

    反射反射,程序员的快乐,今天你快乐了吗?如果你不快乐,没关系,接下来让你快乐起来! 一.什么是反射? 通过百度百科我们可以知道,Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性 ...

  5. 对于java反射的理解

    java中的反射是一种强大的工具,它能够创建灵活的代码,这些代码可以在运行时装配,无序在组件之间进行链接. 反射允许在编写与执行时,使程序代码能够接入装载到JVM的类的内部信息,而不是源代码中选定的类 ...

  6. 通过Java反射来理解泛型的本质

    集合框架中经常会使用泛型指定集合中所存放元素的类型,保证集合的统一性,从集合中取出元素的时候也避免了类型强制转换的操作,所以我们使用常规的方式来往集合中存放元素的时候,如果指定泛型,那么我们只能向集合 ...

  7. java反射知识点总结

    一.java反射基础 1.1 什么叫java反射? 答:程序运行期间,动态的获取类的基本信息.比如:创建对象,调用类的方法,获得类的基本结构.这样给程序设计提供了很大的灵活性.个人总结就是:根据动态需 ...

  8. Java反射学习:深入学习Java反射机制

    一.Java反射的理解(反射是研究框架的基础之一) Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的 ...

  9. java反射机制 + Method.invoke解释 getMethod + 反射理解

    功能: 通过读取另一个Dll去创建一个控件(Form,Button,TextBox,DataGridView),然后对当中一些属性进行检查. 创建控件的大致流程是,Assembly->Modul ...

随机推荐

  1. winform中如何在TextBox中只能输入数字(可以带小数点)

    可以采用像web表单验证的方式,利用textbox的TextChanged事件,每当textbox内容变化时,调用正则表达式的方法验证,用一个label在text后面提示输入错误,具体代码如下: pr ...

  2. C# winform如何在textbox中判断输入的是字母还是数字?

    1.用正规式using System.Text.RegularExpressions; string pattern = @"^\d+(\.\d)?$";if(Text1.Text ...

  3. Java通过代理server上网

    完整代码 package com.proj.net; //导入编码的jar文件 import it.sauronsoftware.base64.Base64; import java.io.Buffe ...

  4. TREEVIEW拖拽对应修改目录

    附件:http://files.cnblogs.com/xe2011/TreeView_Drag_Directory%E6%93%8D%E4%BD%9C.rar     TREEVIEW拖拽对应修改目 ...

  5. mybatis09

    1mybatis开发dao的方法 .1SqlSession作用范围 是使用局部变量.成员变量,还是形参? 1.1.1SqlSessionFactoryBuilder SqlSessionFactory ...

  6. Mysql show Status参数详解

    状态名 作用域 详细解释 Aborted_clients Global 由于客户端没有正确关闭连接导致客户端终止而中断的连接数 Aborted_connects Global 试图连接到MySQL服务 ...

  7. QuaZip实现多文件打包

    项目需求: 在Goldenfarm客户端中当用户选择了本地场景文件,并进行本地场景文件分析后会产生分析结果,分析结果主要包括:贴图纹理.可渲染层等,其中贴图纹理指出了在场景文件中使用到的贴图或其它文件 ...

  8. binary heap

    In computer science, a heap is a specialized tree-based data structure that satisfies the heap prope ...

  9. ARCGIS二维三维互动

    当对三维模型进行操作时(如导航.平移)二维地图自动跟进. private void Synckron() { m_pGlobe = this._GlobeControl.Globe; m_pMap = ...

  10. Ⅱ.AngularJS的点点滴滴--缓存

    模板缓存-$templateCache and 缓存工厂 $cacheFactory 1.使用script标签 <html ng-app> <script src="htt ...