- 浏览: 685987 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (297)
- J2SE (78)
- swt/飞信 (20)
- mysql/mssql (17)
- 设计模式 (5)
- windows (18)
- 闲言碎语 (19)
- struts 1.x (6)
- JVM (6)
- tomcat/jetty (8)
- jquery/javascript (15)
- web前端 (6)
- J2EE (0)
- PHP (6)
- 算法设计 (17)
- 数据结构 (3)
- C/C++ (6)
- linux (19)
- 程序打包 (8)
- eclipse/myeclipse (10)
- 其他杂项 (13)
- 应聘 (9)
- spring/spring mvc (4)
- Maven/Ant (2)
- ERROR (1)
- nosql/hbase (1)
- hibernate (3)
- Solr/Lucene (1)
最新评论
-
乔木1937:
太感谢了,看到你的文章终于解决这个问题了!
[转载]通过端口 1433 连接到主机 localhost 的 TCP/IP 连接失败。错误:“Connection refused: connect。 -
xianweisi:
竟然还有马
精简JRE - 实例Swing计算器 with 精简JRE(续) -
Javkburd:
我刚也遇到这个问题,然后也把默认端口改成了1433,只差最后没 ...
[转载]通过端口 1433 连接到主机 localhost 的 TCP/IP 连接失败。错误:“Connection refused: connect。 -
yeshaoting:
kingbinchow 写道 最近的爪哇岛 没有什么货进项呀 ...
jQuery方法区别(四)click() bind() live() delegate()区别 -
kingbinchow:
最近的爪哇岛 没有什么货进项呀!
jQuery方法区别(四)click() bind() live() delegate()区别
[学习]Java反射机制
1. 三类成员Constructor, Field, Method
java.lang.reflect.Member 是一种接口,反映有关单个成员(字段或方法)或构造函数的标识信息。
所有已知实现类: Constructor, Field, Method
2. 二个字段PUBLIC, DECLARED
java.lang.reflect.Member 接口有二个字段:
int java.lang.reflect.Member.PUBLIC = 0 [0x0]
Identifies the set of all public members of a class or interface, including inherited members.
说明:标识类或接口的所有公共成员(包括继承成员)的集合。
int java.lang.reflect.Member.DECLARED = 1 [0x1]
Identifies the set of declared members of a class or interface. Inherited members are not included.
说明:标识类或接口的所有已声明成员的集合。不包括继承成员。
注:接口是可以有字段的,接口中的字段必须用public static final来修饰,默认如此,可不必添加。这是与接口只能被实现有关。
3. 三类方法getXXXConstructorX, getXXXFieldX, getXXXMethodX
这些方法根据成员类型,成员访问权限不同可简单归为以上三类。
中间加有Declared的方法能够调用所有已声明成员的集合,但不包括继承成员。
中间没有Declared的方法能够调用所有公共成员(包括继承成员)的集合。
未尾加有s的方法返回所有对应的成员集,e.g. getConstructors()返回所有公共构造方法。
a. 调用构造函数(Constructor)的方法 - getXXXConstructorX(),包括:
getConstructor(), getConstructors(),
getDeclaredConstructor(), getDeclaredConstructors()
b. 调用字段(Field)的方法 - getXXXFieldX()
getField(), getFields(),
getDeclaredField(), getDeclaredFields()
c. 调用方法(Method)的方法 - getXXXMethodX()
getMethod(), getMethods(),
getDeclaredMethod(), getDeclaredMethods()
4. 调用构造函数的方法一般步骤
a. 返回与带有给定字符串名的类或接口相关联的 Class 对象。调用此方法等效于:
Class.forName(className, true, currentLoader)
其中 currentLoader 表示当前类的定义类加载器。
public static Class<?> forName(String className)
throws ClassNotFoundException
b. 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。parameterTypes 参数是 Class 对象的一个数组,这些 Class 对象按声明顺序标识构造方法的形参类型。 如果此 Class 对象表示非静态上下文中声明的内部类,则形参类型作为第一个参数包括显示封闭的实例。
无参构造函数,parameterTypes可以为空,可以为null,可以为new Class[]{}。
有参构造函数,parameterTypes为各参数类型。
e.g.
基本类型:int.class,long.class,...
类/接口类型:String.class,List.class,...
数组类型:long[].class,String[].class,...
public Constructor<T> getConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException
c. 使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。个别参数会自动解包,以匹配基本形参,必要时,基本参数和引用参数都要进行方法调用转换。
无参构造函数,parameterTypes可以为空,可以为null,可以为new Object[]{}
public T newInstance(Object ... initargs)
throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException
5. 调用字段的方法一般步骤
a. 返回与带有给定字符串名的类或接口相关联的 Class 对象。调用此方法等效于:
Class.forName(className, true, currentLoader)
其中 currentLoader 表示当前类的定义类加载器。
public static Class<?> forName(String className)
throws ClassNotFoundException
b. 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。name 参数是一个 String,它指定所需字段的简称。注意,此方法不反映数组类的 length 字段。
一般JavaBean中的字段都被 private 修饰,所以使用getDeclaredField(String name)方法。
注:getField(String name)方法,会因为只能访问公有成员而出错。
public Field getField(String name)
throws NoSuchFieldException, SecurityException
public Field getDeclaredField(String name)
throws NoSuchFieldException, SecurityException
c. 返回指定对象上此 Field 表示的字段的值。如果该值是一个基本类型值,则自动将其包装在一个对象中。
底层字段的值是按以下方式获得的:
如果底层字段是一个静态字段,则忽略 obj 变量;它可能为 null。 否则,底层字段是一个实例字段。如果指定的 obj 变量为 null,则该方法将抛出一个 NullPointerException。如果指定对象不是声明底层字段的类或接口的实例,则该方法将抛出一个 IllegalArgumentException。如果此 Field 对象强制实施 Java 语言访问控制,并且底层字段是不可访问的,则该方法将抛出一个 IllegalAccessException。
如果底层字段是静态的,并且声明该字段的类尚未初始化,则初始化这个类。否则,从底层实例字段或静态字段中获取该值。如果该字段是一个基本类型字段,则在返回前将该值包装在一个对象中,否则照原样返回。 如果字段隐藏在 obj 的类型中,则根据前面的规则获得字段的值。
除了通用的方法Object get(Object obj)外,还有int getInt(Object obj),long getLong(Object obj)等用来返回基本类型值的方法。
注:
1. Object obj 是包含有该字段的类实例
2. 调用方法用来返回某个字段值,需要遵循权限访问规则。若字段在当前方法中不可见,则无法访问,抛出异常。可见,调用字段方法一般用来获取其字段信息,而不会用来直接设置、获取其字段值。若想设置、获取其值,则可以通过getter/setter方法来完成。
public Object get(Object obj)
throws IllegalArgumentException, IllegalAccessException
6. 调用方法的方法一般步骤
a. 返回与带有给定字符串名的类或接口相关联的 Class 对象。调用此方法等效于:
Class.forName(className, true, currentLoader)
其中 currentLoader 表示当前类的定义类加载器。
public static Class<?> forName(String className)
throws ClassNotFoundException
b. 返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。name 参数是一个 String,用于指定所需方法的简称。parameterTypes 参数是按声明顺序标识该方法形参类型的 Class 对象的一个数组。如果 parameterTypes 为 null,则按空数组处理。
public Method getMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException
c. 对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。个别参数被自动解包,以便与基本形参相匹配,基本参数和引用参数都随需服从方法调用转换。
如果底层方法是静态的,那么可以忽略指定的 obj 参数。该参数可以为 null。
如果底层方法所需的形参数为 0,则所提供的 args 数组长度可以为 0 或 null。
如果底层方法是实例方法,则使用动态方法查找来调用它,这一点记录在 Java Language Specification, Second Edition 的第 15.12.4.4 节中;在发生基于目标对象的运行时类型的重写时更应该这样做。
如果底层方法是静态的,并且尚未初始化声明此方法的类,则会将其初始化。
如果方法正常完成,则将该方法返回的值返回给调用者;如果该值为基本类型,则首先适当地将其包装在对象中。但是,如果该值的类型为一组基本类型,则数组元素不被包装在对象中;换句话说,将返回基本类型的数组。如果底层方法返回类型为 void,则该调用返回 null。
注:Object obj 是包含有该字段的类实例
public Object invoke(Object obj, Object... args)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException
实例:
/**
* Copyright (c) 2011 Trusted Software and Mobile Computing(TSMC)
* All right reserved.
*
* Created on Aug 19, 2011 12:12:06 PM
* http://jarg.iteye.com/
* Author: Jarg Yee <yeshaoting@gmail.com>
*/
package com.iteye.jarg.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* TODO [学习]Java反射机制
*/
public class ReflectEx
{
public static void main(String[] args) throws Exception
{
Class<?> clazz = Class.forName("com.iteye.jarg.test.ReflectBean");
//无参构造函数参数数组可不写,可用new Class[]{},可用null
Constructor<?> constructor = clazz.getConstructor();
//无参构造函数参数数组可不写,可用new Object[]{},可用null
Object obj = constructor.newInstance();
ReflectBean bean = (ReflectBean)obj;
bean.display("1");
constructor = clazz.getConstructor(String.class);
obj = constructor.newInstance("字段 name 参数值");
bean = (ReflectBean)obj;
bean.display("2");
//虽然getDeclaredField能查看字段相关信息,但是获取字段值还得遵循权限访问规则
//若使用getField("name"),则会因为它只能访问公共成员而出错
Field field = clazz.getDeclaredField("name");
//获取实例相应字段值,而不是字段初始值
System.out.println("3. name:\t" + field.get(bean));
System.out.println("-------------------------------");
Object obj2 = clazz.newInstance();
Method method = clazz.getMethod("setName", String.class);
method.invoke(obj2, "字段 name 全新值");
bean = (ReflectBean)obj2;
bean.display("4");
obj2 = clazz.newInstance();
method = clazz.getMethod("setValue", int[].class);
method.invoke(obj2, new int[]{1,2,3,4});
bean = (ReflectBean)obj2;
System.out.println("5. value:\t" + bean.getValue()[2]);
}
}
class ReflectBean
{
int[] value = new int[4];
String name = "字段 name 初始值";
public ReflectBean(String name)
{
this.name = name;
System.out.println("测试 \"有\" 参构造函数");
}
public ReflectBean()
{
System.out.println("测试 \"无\" 参构造函数");
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public int[] getValue()
{
return value;
}
public void setValue(int[] value)
{
this.value = value;
}
public void display(String id)
{
System.out.println(id + ". name:\t" + name);
System.out.println("-------------------------------");
}
}
输出结果:
测试 "无" 参构造函数 1. name: 字段 name 初始值 ------------------------------- 测试 "有" 参构造函数 2. name: 字段 name 参数值 ------------------------------- 3. name: 字段 name 参数值 ------------------------------- 测试 "无" 参构造函数 4. name: 字段 name 全新值 ------------------------------- 测试 "无" 参构造函数 5. value: 3
发表评论
-
Java - Convert String to enum
2012-11-17 22:03 1912http://stackoverflow.com/que ... -
[ERROR]Premature end of file
2012-09-28 11:41 3350[ERROR]Premature end of file ... -
测试java.util.Map.Entry
2012-07-18 16:13 1021/** * Copyright (c) 201 ... -
关于eclipse启动出错问题的解决办法
2012-06-09 09:31 1485转自:http://blog.csdn.net/jkpt ... -
Myeclipse中把java代码导成UML类图
2012-05-18 14:53 2371MyEclipse 中选择window,在 Open ... -
[转载]java synchronized详解
2012-05-15 17:18 868http://www.cnblogs.com ... -
[转载]Java 根据 HashMap 的 value 进行排序
2012-05-08 09:58 952转载:http://www.oschina.net/co ... -
JAVA实时屏幕监控
2012-04-29 16:13 3324JAVA实时屏幕监控 说明: 本程序会运 ... -
[JAVA实时屏幕监控]JAVA使用Internet代理设置
2012-04-29 14:50 1387JAVA使用Internet代理设置 描述:首先 ... -
[JAVA实时屏幕监控]JAVA通过注册表获取Internet代理设置
2012-04-29 14:47 2338JAVA通过注册表获取Internet代理设置 ... -
[JAVA实时屏幕监控]JAVA发送邮件
2012-04-29 14:28 2507JAVA发送邮件 描述:利用commons-em ... -
[JAVA实时屏幕监控]JAVA屏幕截图
2012-04-29 14:19 1318JAVA屏幕截图 /** * 产生截图 ... -
[JAVA实时屏幕监控]Java使用代理服务器
2012-04-24 13:36 2490/** * Copyright (c) 2012 T ... -
java.util.ConcurrentModificationException解决办法
2012-04-23 10:47 1583java.util.ConcurrentModi ... -
[转载]java.util.ConcurrentModificationException
2012-04-23 09:20 976java.util.ConcurrentModif ... -
整数转换成字节型数组
2012-04-22 13:16 6017整数转换成字节型数组 描述: 整数(in ... -
java.lang.NoClassDefFoundError: javax/mail/Message解决方法
2012-04-18 10:33 1269缺少activation.jar 和 mail.jar ... -
设置javax.swing.JFrame窗口外观
2012-03-29 15:34 0设置javax.swing.JFrame窗口外 ... -
设置javax.swing.JFrame窗口外观
2012-03-29 15:34 0设置javax.swing.JFrame窗口 ... -
Java图形界面外观包substance.jar
2012-03-29 15:33 0一直以来都认为用Swing做出来的程序 ...
相关推荐
通过本文的学习,我们深入了解了Java反射机制的基本概念、原理以及应用。Java反射机制为Java程序提供了一种强大的动态处理能力,使得Java不仅仅局限于静态类型语言的功能限制。掌握Java反射机制对于开发者来说是非常...
Java 反射机制详解及 Method.invoke 解释 Java 反射机制是 Java 语言中的一种功能,允许程序在运行时访问和修改...通过学习 Java 反射机制,可以更好地理解 Java 语言的机理,并且可以更好地开发出高效、灵活的程序。
这篇博文"Java反射机制学习(二)"可能深入探讨了如何利用反射进行动态类型处理、访问私有成员以及创建对象等核心概念。在这里,我们将详细讨论Java反射的基本用法及其在实际开发中的应用。 1. **什么是反射**: ...
Java反射机制是Java编程语言中的一个强大工具,它允许程序在运行时检查并操作类、接口、对象等...虽然视频质量可能不高,但它仍然是学习Java反射机制的重要资源,可以帮助开发者提升编程的灵活性和应对复杂场景的能力。
Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、对象等的内部信息。这一机制对于理解和实现高级框架、动态代理、元数据处理等场景至关重要。以下是对Java反射机制的详细说明:...
关于java反射机制的很好的讲解,包括Java的反射机制(Reflection)、Class类、如何获得类的相关信息和运用,并且还有相应的练习,有助于更好地学习java反射机制
Java反射机制是Java编程语言中的一项核心特性,它允许程序在运行时动态地获取类的信息并进行操作。这使得Java能够在编译后仍然能够灵活地处理类和对象,增强了代码的动态性。在Android应用开发中,反射机制尤其重要...
学习Java反射机制的重要性体现在以下几个方面: 1. 动态类型:反射机制允许我们在运行时检查对象的类型,这对于编写通用代码和处理未知类型的对象非常有用。 2. 插件化开发:在插件化系统中,反射可以用于加载和...
在"北大青鸟java反射机制"的学习资料中,我们将会深入探讨这一核心特性。 首先,我们要理解反射的核心概念:在程序运行时,通过Class对象获取类的信息,包括类名、属性、方法等,并能够动态地创建对象和调用方法。...
总的来说,"JAVA反射机制的入门代码"是初学者理解Java反射机制的好教材,通过它,你可以学习如何动态地操作Java类,提高代码的灵活性,并掌握处理`properties`文件的基础方法。在深入学习和实践中,你将进一步理解...
Java反射机制是Java编程语言中的一个重要特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射机制的核心类集中...在实践中学习,你会更好地理解Java反射机制的威力和应用场景。
Java反射机制是Java编程语言中的一个强大特性,...通过学习和实践Java反射机制,你可以更深入地理解Java的运行机制,并在需要动态性、灵活性的场景中发挥其强大的功能。不过,使用反射时也应注意潜在的风险和性能影响。
Java反射机制是Java编程语言中一个强大的工具,它允许程序在运行时动态地获取类的信息并操作类的对象。反射机制的核心在于java.lang.reflect包中的API,主要包括Class类、Constructor类、Method类和Field类。以下是...
本笔记主要涵盖了四个核心知识点:Java反射机制、流(I/O流)、内存管理和Java学习的基础。以下是对这些主题的详细阐述: 一、Java反射机制 Java反射机制是Java语言的一个强大特性,允许程序在运行时检查类、接口、...
java学习笔记java反射机制
Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、字段以及方法等对象。这一机制的核心在于`java.lang.Class`类和相关的API,它们提供了对类元数据的访问,使得我们能够在运行时...
通过这个例子,新手可以学习到如何使用Java反射机制来增强代码的动态性,以及如何设计可扩展的系统。反射在很多场景下都很有用,例如在插件系统、序列化、动态代理等领域都有广泛应用。然而,需要注意的是,反射也...
自己总结的java反射机制的笔记,绘制了详细的思维导图,每个思维导图中均有详细的博文解释,方便大家学习和理解,免费分享给大家。适合java的爱好者和学习者
学习Java反射机制,你需要理解并掌握这些类的使用,同时要明白,虽然反射提供很大的灵活性,但也带来了性能开销和安全风险,因此在实际开发中应谨慎使用。在自学或教学过程中,第13章的Java反射机制课件会深入讲解...
Java反射机制是Java编程语言中一个强大的特性,它允许运行时的程序动态地获取类的信息并操作类的对象。在Java中,反射主要涉及到`java.lang.Class`类、`java.lang.reflect`包下的类如`Constructor`、`Method`和`...