Java反射的理解

时间:2022-01-19 03:32:53
反射的作用:
 
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. &lpar;转&rpar;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反射机制 &plus; Method&period;invoke解释 getMethod &plus; 反射理解

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

随机推荐

  1. JS打开新页面跳转

      有时候使用js进行页面跳转,想使用 a 标签中 target="_blank" 形式,跳转打开一个新的页面. 可以使用以下脚本,创建一个 a标签,然后模拟点击操作. 代码如下: ...

  2. 如何制作快速加载的HTML页面

    整理出来的tip 减小页面的大小 在页面下载中,页面的大小至今扮演着非常重要的因素. 减小页面的大小能够通过排除不必要空格,注释,动态内嵌脚本,和放入外部文件的 CSS 等在页面结构中很小的改变都能够 ...

  3. linux用户和组管理

    添加组groupadd sftp 把用户mysftp加入组sftp中:gpasswd -a mysftp sftp 把用户mysftp加入组sftp中:usermod -a -G sftp mysft ...

  4. POJ 3692 Kindergarten &lpar;二分图 最大团&rpar;

    Kindergarten Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5660   Accepted: 2756 Desc ...

  5. C&num;实现阻止关闭显示器和系统待机

    原文http://www.cnblogs.com/TianFang/archive/2012/10/12/2721883.html 最近写了一个下载程序,发现有一个问题:挂机下载的时候,下载任务会因为 ...

  6. Linux 最简单的驱动程序hello world

    图片驱动位置:kernel3-10/driver/misc/mediatek/imgsensor/src/mt8127/kd_sensorlist.c 例子:kernel-3.10/driver/mi ...

  7. 2&period;WP8&period;1开发&lowbar;在顶部显示标题和进度

    有时候加载页面的时候,需要在信号那一栏显示进度,或者把信号栏改成标题 1.确保显示状态栏.默认显示.如果不显示,可以在应用程序启动后手动用代码显示,代码如下: //取得状态栏 StatusBar ba ...

  8. Mysql的学习笔记03

    ---恢复内容开始--- Mysql 的视图 1  view  在查询中,我们经常把查询结果当成临时表来看, view 是什么? View 可以看成一张虚拟的表,是表通过某种运算得到的有一个投影. 2 ...

  9. python模块和包(模块、包、发布模块)

    模块和包 目标 模块 包 发布模块 01. 模块 1.1 模块的概念 模块是 Python 程序架构的一个核心概念 每一个以扩展名 py 结尾的 Python 源代码文件都是一个 模块 模块名 同样也 ...

  10. JVM调优(二)经验参数设置

    调优设置具体解析 堆大小设置 JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内存限制:系统的可用物理内存限制.32位系统下,一般限制在1.5 ...