- 浏览: 91951 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
xtpgyaps:
楼主,问下,,怎么我重构了JakartaMultiPartRe ...
struts2 使用 jakarta 上传文件时commons fileupload的异常捕捉 -
netfork:
时间变化真快,楼主08年5月份发的贴,现在再看涉及到的源代码, ...
struts2 使用 jakarta 上传文件时commons fileupload的异常捕捉 -
harry:
不错很不错
Linda Rising:“你相信谁?”
Java动态程序设计:反射介绍 |
muzi_li 翻译 更新:2005-08-05 20:28:38 版本: 1.0 |
Java动态程序设计:反射介绍
使用运行的类的信息使你的程序设计更加灵活
反
射授予了你的代码访问装载进JVM内的Java类的内部信息的权限,并且允许你编写在程序执行期间与所选择的类的一同工作的代码,而不是在源代码中。这种
机制使得反射成为创建灵活的应用程序的强大工具,但是要小心的是,如果使用不恰当,反射会带来很大的副作用。在这篇文章中,软件咨询顾问
Dennis Sosnoski 介绍了反射的使用,同时还介绍了一些使用反射所要付出的代价。在这里,你可以找到Java反射API是如何在运行时让你
钩入对象的。
在第一部分,我向你介绍了Java程序设计的类以及类的装载。那篇文章中描述了很多出现在Java二进制类格式中的信息,现
在我来介绍在运行时使用反射API访问和使用这些信息的基础。为了使那些已经了解反射基础的开发人员对这些事情感兴趣,我还会介绍一些反射与直接访问的在
性能方面的比较。
使用反射与和metadata(描述其它数据的数据)一些工作的Java程序设计是不同的。通过Java语言反射来访问的元数据的特殊类型是在JVM内部的类和对象的描述。反射使你可以在运行时访问各种类信息,它甚至可以你让在运行时读写属性字段、调用所选择的类的方法。
反射是一个强大的工具,它让你建立灵活能够在运行时组装的代码,而不需要连接组件间的源代码。反射的一些特征也带来一些问题。在这章中,我将会探究在应用程序中不打算使用反射的原因,以为什么使用它的原因。在你了解到这些利弊之后,你就会在好处大于缺点的时候做出决定。
初识class
使用反射的起点总时一个java.lang.Class类的实例。如果你与一个预先确定的类一同工作,Java语言为直接获得Class类的实例提供了一个简单的快捷方式。例如:
Class clas = MyClass.class;
当你使用这项技术的时候,所有与装载类有关的工作都发生在幕后。如果你需要在运行时从外部的资源中读取类名,使用上面这种方法是不会达到目的的,相反你需要使用类装载器来查找类的信息,方法如下所示:
// "name" is the class name to load
Class clas = null;
try {
clas = Class.forName(name);
} catch (ClassNotFoundException ex) {
// handle exception case
}
// use the loaded class
如果类已经装载,你将会找到当前在在的类的信息。如果类还没有被装载,那么类装载器将会装载它,并且返回最近创建的类的实例。
关于类的反射
Class
对象给予你了所有的用于反射访问类的元数据的基本钩子。这些元数据包括有关类的自身信息,例如象类的包和子类,还有这个类所实现的接口,还包括这个类所定
义的构造器、属性字段以及方法的详细信息。后面的这些项是我们在程序设计过种经常使用的,因此在这一节的后面我会给出一些用这些信息来工作的例子。
对于类的构造中的每一种类型(构造器、属性字段、方法),java.lang.Class提供了四种独立的反射调用以不的方式来访问类的信息。下面列出了这四种调用的标准形式,它是一组用于查找构造器的调用。
Constructor getConstructor(Class[] params) 使用指定的参数类型来获得公共的构造器;
Constructor[] getConstructors() 获得这个类的所有构造器;
Constructor getDeclaredConstructor(Class[] params) 使用指定的参数类型来获得构造器(忽略访问的级别)
Constructor[] getDeclaredConstructors() 获得这个类的所有的构造器(忽略访问的级别)
上
述的每一种方法都返回一或多个java.lang.reflect.Constructor的实例。Constructor类定义了一个需要一个对象数据
做为唯一参数的newInstance方法,然后返回一个最近创建的原始类的实例。对象数组是在构造器调用时所使用的参数值。例如,假设你有一个带有一对
String 类型做为参数的构造器的TwoString类,代码如下所示:
public class TwoString {
private String m_s1, m_s2;
public TwoString(String s1, String s2) {
m_s1 = s1;
m_s2 = s2;
}
}
下面的代码显示如何获得TwoString类的构造器,并使用字符串“a”和“b”来创建一个实例:
Class[] types = new Class[] { String.class, String.class };
Constructor cons = TwoString.class.getConstructor(types);
Object[] args = new Object[] { "a", "b" };
TwoString ts = cons.newInstance(args);
上面的代码忽略了几种可能的被不同的反射方法抛出的异常检查的类型。这些异常在Javadoc API中有详细的描述,因此为简便起见,我会在所有的代码中忽略它们。
在我涉及到构造器这个主题时,Java语言也定义了一个特殊的没有参数的(或默认)构造器快捷方法,你能使用它来创建一个类的实例。这个快捷方法象下面的代码这样被嵌入到类的自定义中:
Object newInstance() ?使用默认的构造器创建新的实例。
尽管这种方法只让你使用一个特殊的构造器,但是如果你需要的话,它是非常便利的快捷方式。这项技术在使用JavaBeans工作的时候尤其有用,因为JavaBeans需要定义一个公共的、没有参数的构造器。
通过反射来查找属性字段
Class类反射调用访问属性字段信息与那些用于访问构造器的方法类似,在有数组类型的参数的使用属性字段名来替代:使用方法如下所示:
Field getField(String name) --获得由name指定的具有public级别的属性字段
Field getFields() ?获得一个类的所有具有public级别的属性字段
Field getDeclaredField(String name) ?获得由name指定的被类声明的属性字段
Field getDeclaredFields() ?获得由类定义的所有的属性字段
尽管与构造器的调用很相似,但是在提到属性字段的时候,有一个重要的差别:前两个方法返回能过类来访问的公共(public)属性字段的信息(包括那些来自于超类的属性字段),后两个方法返回由类直接声明的所有的属性字段(忽略了属性字段的访问类型)。
Java.lang.reflect.Field
的实例通过调用定义好的getXXX和setXXX方法来返回所有的原始的数据类型,就像普通的与对象引用一起工作的get和set方法一样。尽管
getXXX方法会自动地处理数据类型转换(例如使用getInt方法来获取一个byte类型的值),但使用一个适当基于实际的属性字段类型的方法是应该
优先考虑的。
下面的代码显示了如何使用属性字段的反射方法,通过指定属性字段名,找到一个对象的int类型的属性字段,并给这个属性字段值加1。
public int incrementField(String name, Object obj) throws... {
Field field = obj.getClass().getDeclaredField(name);
int value = field.getInt(obj) + 1;
field.setInt(obj, value);
return value;
}
这个方法开始展现一些使用反射所可能带来的灵活性,它优于与一个特定的类一同工作,incrementField方法把要查找的类信息的对象传递给getClass方法,然后直接在那个类中查找命名的属性字段。
通过反射来查找方法
Class反射调用访问方法的信息与访问构造器和字段属性的方法非常相似:
Method getMethod(String name,Class[] params) --使用指定的参数类型获得由name参数指定的public类型的方法。
Mehtod[] getMethods()?获得一个类的所有的public类型的方法
Mehtod getDeclaredMethod(String name, Class[] params)?使用指定的参数类型获得由name参数所指定的由这个类声明的方法。
Method[] getDeclaredMethods() ?获得这个类所声明的所有的方法
与属性字段的调用一样,前两个方法返回通过这个类的实例可以访问的public类型的方法?包括那些继承于超类的方法。后两个方法返回由这个类直接声明的方法的信息,而不管方法的访问类型。
通过调用返回的Java.lang.reflect.Mehtod实例定义了一个invoke方法,你可以使用它来调用定义类的有关实例。这个invoke方法需要两个参数,一个是提供这个方法的类的实例,一个是调用这个方法所需要的参数值的数组。
下
面给出了比属性字段的例子更加深入的例子,它显示了一个的方法反射的例子,这个方法使用get和set方法来给JavaBean定义的int类型的属性做
增量操作。例如,如果对象为一个整数类型count属性定义了getCount和setCount方法,那么为了给这个属性做增量运算,你就可以把
“count”做为参数名传递给调用的这个方法中。示例代码如下:
public int incrementProperty(String name, Object obj) {
String prop = Character.toUpperCase(name.charAt(0)) +
name.substring(1);
String mname = "get" + prop;
Class[] types = new Class[] {};
Method method = obj.getClass().getMethod(mname, types);
Object result = method.invoke(obj, new Object[0]);
int value = ((Integer)result).intValue() + 1;
mname = "set" + prop;
types = new Class[] { int.class };
method = obj.getClass().getMethod(mname, types);
method.invoke(obj, new Object[] { new Integer(value) });
return value;
}
根
据JavaBeans的规范,我把属性名的第一个字母转换为大写,然后在前面加上“get”来建立读取属性值的方法名,在属性名前加上“set”来建立设
置属性值的方法名。JavaBeans的读方法只返回属性值,写方法只需要要写入的值做为参数,因此我指定了与这个方法相匹配的参数类型。最后规范规定这
两个方法应该是public类型的,因此我使用了查找相关类的public类型方法的调用形式。
这个例子我首先使用反射传递一个原始类型
的值,因此让我们来看一下它是怎样工作的。基本的原理是简单的:无论什么时候,你需要传递一个原始类型的值,你只要替换相应的封装原始类型的(在
java.lang 包中定义的)的类的实例就可以了。这种方法可应用于调用和返回。因此在我的例子中调用get方法时,我预期的结果是一个由
java.lang.Integer类所封装的实际的int类型的属性值。
反射数组
在Java语言中数组是对象,象其它
所有的对象一样,它有一些类。如果你有一个数组,你可以和其它任何对象一样使用标准的getClass方法来获得这个数组的类,但是你获得的这个类与其它
的对象类型相比,不同之处在它没有一个现存的工作实例。即使你有了一个数组类之后,你也不能够直接用它来做任何事情,因为通过反射为普通的类所提供的构造
器访问不能为数组工作,并且数组没有任何可访问的属性字段,只有基本的为数组对象定义的java.lang.Object类型的方法。
数组特殊处理要使用java.lang.reflect.Array类提供的一个静态方法的集合,这个类中的方法可以让你创建新的数组,获得一个数组对象的长度,以及读写一个数组对象的索引值。
下面的代码显示了有效调整一个现存数组的尺寸的方法。它使用反射来创建一个相同类型的新数组,然后在返回这个新数组之前把原数组中的所有的数据复制到新的数组中。
public Object growArray(Object array, int size) {
Class type = array.getClass().getComponentType();
Object grown = Array.newInstance(type, size);
System.arraycopy(array, 0, grown, 0,
Math.min(Array.getLength(array), size));
return grown;
}
安全与反射
在处理反射的时候,安全是一个复杂的问题。反射正常被框架类型的代码使用,并因为这样,你可能会经常要求框架不关心普通的访问限制来完全访问你的代码。然而,自由的访问可能会在其它的一些实例中产生一些风险,例如在代码在一个不被信任的代码共享环境中被执行的时候。
因为这些冲突的需要,Java语言定义了一个多级方法来处理反射安全。基本的模式是在反射请求源码访问的时候强制使用如下相同的约束限制:
访问这个类中来自任何地方的public组件;
不访问这个类本身外部的private组件;
限制访问protected和package(默认访问)组件。
围
绕这些限制有一个简单的方法,我在前面的例子中所使用的所有构造器、属性字段、以及类的方法都扩展于一个共同的基
类???java.lang.reflect.AccessibleObject类。这个类定义了一个setAccessible方法,这个方法可以让你
打开或关闭这些对类的实例的访问检查。如果安全管理器被设置为关闭访问检查,那么就允许你访问,否则不允许,安全管理器会抛出一个异常。
下面是一个使用反向来演示这种行为的TwoString类的实例。
public class ReflectSecurity {
public static void main(String[] args) {
try {
TwoString ts = new TwoString("a", "b");
Field field = clas.getDeclaredField("m_s1");
// field.setAccessible(true);
System.out.println("Retrieved value is " +
field.get(inst));
} catch (Exception ex) {
ex.printStackTrace(System.out);
}
}
}
如
果你编译这段代码并且直接使用不带任何参数的命令行命令来运行这个程序,它会抛出一个关于field.get(inst)调用的
IllegalAccessException异常,如果你去掉上面代码中field.setAccessible(true)行的注释,然后编译并重新
运行代码,它就会成功执行。最后,如果你在命令行给JVM添加一个Djava.security.manager参数,使得安全管理器可用,那么它又会失
败,除非你为ReflectSecurity类定义安全许可。
反射性能
反射是一个强大的工具,但是也会带一些缺点。主要缺点之一
就是对性能的影响。使用反射是基本的解释性操作,你告诉JVM你要做什么,它就会为你做什么。这种操作类型总是比直接做同样的操作要慢。为了演示使用反射
所要付出的性能代价,我为这篇文章准备了一套基准程序(可以从资源中下载)。
下面列出一段来自于属性字段的访问性能测试的摘要,它包括基
本的测试方法。每个方法测试一种访问属性字段的形式,accessSame方法和本对象的成员字段一起工作,accessReference方法直接使用
另外的对象属性字段来存取,accessReflection通过反射使用另一个对象的属性字段来存取,每个方法都使用相同的计算???在循环中简单的加
/乘运算。
public int accessSame(int loops) {
m_value = 0;
for (int index = 0; index < loops; index++) {
m_value = (m_value + ADDITIVE_VALUE) *
MULTIPLIER_VALUE;
}
return m_value;
}
public int accessReference(int loops) {
TimingClass timing = new TimingClass();
for (int index = 0; index < loops; index++) {
timing.m_value = (timing.m_value + ADDITIVE_VALUE) *
MULTIPLIER_VALUE;
}
return timing.m_value;
}
public int accessReflection(int loops) throws Exception {
TimingClass timing = new TimingClass();
try {
Field field = TimingClass.class.
getDeclaredField("m_value");
for (int index = 0; index < loops; index++) {
int value = (field.getInt(timing) +
ADDITIVE_VALUE) * MULTIPLIER_VALUE;
field.setInt(timing, value);
}
return timing.m_value;
} catch (Exception ex) {
System.out.println("Error using reflection");
throw ex;
}
}
测
试程序在一个大循环中反复的调用每个方法,在调用结束后计算平均时间。每个方法的第一次调用不包括在平均值中,因些初始化时间不是影响结果的因素。为这篇
文章所做的测试运行,我为每个调用使用了10000000的循环计数,代码运行在1GHz PIII系统上。并且分别使用了三个不同的Linux
JVM,对于每个JVM都使用了默认设置,测试结果如下图所示:
上面的图表的刻度可以显示整个测试范围,但是那样的话就会减少
差别的显示效果。这个图表中的前两个是用SUN的JVM的进行测试的结果图,使用反射的执行时间比使用直接访问的时间要超过1000多倍。最后一个图是用
IBM的JVM所做的测试,通过比较要SUN的JVM执行效率要高一些,但是使用反射的方法依然要比其它方法超出700多倍。虽然IBM的JVM要比
SUN的JVM几乎要快两倍,但是在使用反射之外的两种方法之间,对于任何的JVM在执行效率上没有太大的差别。最大的可能是,这种差别反映了通过
Sun Hot Spot JVMs在简化基准方面所做的专门优化很少。
除了属性字段访问时间的测试以外,我对方法做了同样的测试。对于方法的调用,我偿试了与属性字段访问测试一样的三种方式,用额外使用了没有参数的方法的变量与传递并返回一个值的方法调用相对比。下面的代码显示了使用传递并返回值的调用方式进行测试的三种方法。
public int callDirectArgs(int loops) {
int value = 0;
for (int index = 0; index < loops; index++) {
value = step(value);
}
return value;
}
public int callReferenceArgs(int loops) {
TimingClass timing = new TimingClass();
int value = 0;
for (int index = 0; index < loops; index++) {
value = timing.step(value);
}
return value;
}
public int callReflectArgs(int loops) throws Exception {
TimingClass timing = new TimingClass();
try {
Method method = TimingClass.class.getMethod
("step", new Class [] { int.class });
Object[] args = new Object[1];
Object value = new Integer(0);
for (int index = 0; index < loops; index++) {
args[0] = value;
value = method.invoke(timing, args);
}
return ((Integer)value).intValue();
} catch (Exception ex) {
System.out.println("Error using reflection");
throw ex;
}
}
下
图显示我使用这些方法的测试结果,这里再一次显示了反射要比其它的直接访问要慢很多。虽然对于无参数的案例,执行效率从SUN1.3.1JVM的慢几百倍
到IBM的JVM慢不到30倍,与属性字段访问案例相比,差别不是很大,这种情况的部分原因是因为java.lang.Integer的包装器需要传递和
返回int类型的值。因为Intergers是不变的,因此就需要为每个方法的返回生成一个新值,这就增加了相当大的系统开销。
反
射的性能是SUN在开发1.4JVM时重点关注的一个领域,从上图可以看到改善的结果。Sun1.4.1JVM对于这种类型的操作比1.3.1版有了很大
的提高,要我的测试中要快大约7倍。IBM的1.4.0JVM对于这种测试提供了更好的性能,它的运行效率要比Sun1.4.1JVM快两到三倍。
我
还为使用反射创建对象编写了一个类似的效率测试程序。虽然这个例子与属性字段和方法调用相比差别不是很大,但是在Sun1.3.1JVM上调用
newInstance()方法创建一个简单的java.lang.Object大约比直接使用new Object()方法长12倍的时间,在
IBM1.4.0JVM上大约要长4倍的时间,在Sun1.4.1JVM上大约要长2倍的时间。对于任何用于测试的JVM,使用
Array.newInstance(Type,size)方法创建一个数组所需要的时间比使用new tye[size]所花费的时间大约要长两倍,随
着数组民尺寸的增长,这两种方法的差别的将随之减少。
反射概要总结
Java 语言的反射机制提供了一种非常通用的动态连
接程序组件的方法。它允许你的程序创建和维护任何类的对象(服从安全限制),而不需要提前对目标类进行硬编码。这些特征使得反射在创建与对象一同工作的类
库中的通用方法方面非常有用。例如,反射经常被用于那些数据库,XML、或者其它的外部的持久化对象的框架中。
反射还有两个缺点,一个是
性能问题。在使用属性字段和方法访问的时候,反射要比直接的代码访问要慢很多。至于对影响的程度,依赖于在程序中怎样使用反射。如果它被用作一个相关的很
少发生的程序操作中,那么就不必关心降低的性能,即使在我的测试中所展示的最耗时的反射操作的图形中也只是几微秒的时间。如果要在执行应用程序的核心逻辑
中使用反射,性能问题才成为一个要严肃对象的问题。
对于很多应用中的存在的缺点是使用反射可以使你的实际的代码内部逻辑变得模糊不清。程
序员都希望在源代码中看到一个程序的逻辑以及象绕过源代码的反射所可能产生的维护问题这样的一些技术。反射代码也比相应的直接代码要复杂一些,就像在性能
比较的代码实例看到那样。处理这些问题的最好方法是尽可能少使用反射,只有在一些增加灵活性的地方来使用它。
在下一篇文章中,我将给出一
个更加详细的如何使用反射的例子。这个例子提供了一个用于处理传递给一个Java应用程序的命令行参数的API。在避免弱点的同时,它也显示了反射的强大
的功能,反射能够使用的你的命令处理变得的简单吗?你可以在Java 动态程序设计的第三部分中找到答案。
发表评论
-
[转]javaIo
2011-03-29 20:58 803Java I/O系统的类实在是太多了,这里我们只学习一些基本的 ... -
java IO包和设计模式分析
2011-03-17 14:50 0http://hi.baidu.com/langchao826 ... -
Log4J使用完全手册
2010-10-18 15:23 657Log4J使用完全手册 1 20 ... -
反射实现 AOP 动态代理模式(Spring AOP 的实现 原理)转
2010-07-21 17:07 1002实AOP的意思就是面向切面编程.OO注重的是我们解 ... -
[转]Spring事务配置的五种方式
2010-06-13 16:49 770Spring事务配置的五种方式(http://www. ... -
jetty 使用整理
2008-11-26 11:59 23651.整合eclipse 2.由于使用了内存映射文件,所以会 ... -
[转载]Commons-logging + Log4j 入门指南
2008-10-31 10:34 968Commons-logging + Log4j ... -
MethodInvokingTimerTaskFactoryBean 的使用
2008-07-02 16:45 2171集成TimerTask 容易造成对业务代码的侵入,这种方式更符 ... -
java5新特性
2008-06-27 09:53 1040Java 5.0发布了,许多人都将开始使用这个JDK版本的一些 ... -
osgi实战,学习笔记
2008-05-12 14:57 2313很久就了解了一些OSGI. ...
相关推荐
《Java语言程序设计(基础篇+进阶篇)第六版》是Java学习的重要参考资料,尤其对于初学者和希望深入理解Java编程概念的人来说,这是一本不可多得的教材。本书分为基础篇和进阶篇,涵盖了Java编程的各个方面,旨在帮助...
《Java语言程序设计 进阶篇(原书第8版)》是一本深入探讨Java编程技术的权威书籍,旨在帮助读者提升对Java编程语言的掌握程度。这本书详细讲解了Java的高级特性和复杂概念,是Java程序员进阶的必备读物。 首先,书...
《Java语言程序设计.基础篇(原书第8版)》是学习Java编程的经典教材,适合初学者入门。这本书深入浅出地介绍了Java语言的基础知识,涵盖了编程的基本概念和技术。以下将围绕Java语言的核心概念、关键特性以及在本书中...
在Java程序设计的进阶领域,有多个关键知识点值得深入探讨: 1. **多线程**:Java以其强大的多线程支持而著名。进阶篇会详细讲解如何创建和管理线程,使用守护线程,同步机制如`synchronized`关键字、`java.util....
Java程序设计思想是编程领域的核心概念,它不仅仅是关于语法和函数调用,更是关于如何构建高效、可维护、可扩展的软件系统。本书的核心目的是帮助新手程序员理解和掌握这些设计原则和最佳实践,从而提升他们的编程...
它的设计目标是“一次编写,到处运行”,这意味着编写的Java程序可以在任何支持Java的平台上运行,无需重新编译。这得益于Java的跨平台特性,即Java虚拟机(JVM)。 源代码是程序的原始文本形式,它由程序员编写并...
根据给定的信息,“Java语言程序设计”这一课程主要面向的是中国石油大学(北京)远程教育学院的学生们。从描述来看,这份资料似乎是一份学习指南或者是考试复习资料的一部分,旨在帮助学生们更好地掌握Java编程的...
Java语言程序设计是计算机科学领域中的一门重要课程,尤其对于初学者来说,掌握其基本概念、语法和编程思想至关重要。梁勇编著的《Java语言程序设计》第十版是一本广泛使用的教材,旨在帮助读者深入理解Java编程。这...
《Java语言程序设计提高篇+进阶篇第十版》是一本深入探讨Java编程技术的权威著作,适合已经掌握Java基础的开发者进一步提升自己的技能。这本书的第十版充分反映了Java语言的最新发展,包括Java 8及更高版本的重要...
《Java语言程序设计 基础篇 第10版 梁勇 答案》是一本针对初学者和进阶者的重要参考资料,由知名Java教育专家梁勇编写。本书全面覆盖了Java语言的基础概念、语法和编程技巧,旨在帮助读者深入理解并掌握Java编程的...
《Java程序设计》是唐大仕撰写的一本深入讲解Java编程技术的著作,该书针对初学者和有经验的开发者提供了全面的Java学习资源。在本压缩包中,包含了这本书的电子版,对于想要深入了解Java编程语言的人来说,是一份...
在《Java程序设计(第二版)》一书中,作者深入浅出地介绍了Java编程语言的基本概念和核心特性。这本书的习题旨在帮助读者巩固理论知识,提升实践技能。以下是针对该书习题答案的详细知识点解析: 1. **Java基础...
9. **Java反射与注解**:反射机制让Java在运行时可以动态访问类信息,注解则为代码提供了元数据,书中会讲解它们的使用场景和操作方法。 10. **Java虚拟机(JVM)**:理解JVM对于优化程序性能至关重要,书中可能...
【Java语言程序设计精品课件】是一套深度探讨Java编程的教育资源,旨在为学习者提供全面而深入的Java知识体系。课程内容丰富,涵盖了从基础语法到高级特性的方方面面,适合初学者和有一定经验的开发者进一步提升技能...
Java程序设计精讲课件是一套全面讲解Java编程的教育资源,主要涵盖了泛型、集合类、Java输入输出以及反射等核心概念。这套课程旨在帮助初学者深入理解和熟练掌握Java编程技术,同时也适合有一定基础的开发者进行知识...
在Java程序设计中,有几个关键知识点是必不可少的: 1. **面向对象编程(OOP)**:Java是一种纯面向对象的语言,它强调将数据和操作数据的方法封装在一起,形成对象。类是对象的蓝图,接口定义了对象的行为规范。...
完整版 Java高级教程 Java语言程序设计 第5章 Java反射(共9页).ppt 完整版 Java高级教程 Java语言程序设计 第6章 常用设计模式(共25页).ppt 完整版 Java高级教程 Java语言程序设计 第7章 Java注解(共10页).ppt...
总之,Java反射机制为开发者提供了极大的灵活性,能够在运行时探索和操作类的内部细节,从而实现高度动态的程序设计。然而,过度使用反射可能会降低代码可读性和性能,因此应当权衡利弊,合理运用。
Java语言程序设计是计算机科学与技术专业的重要课程之一,它主要教授如何使用Java语言进行软件开发。本资料《JAVA语言程序设计》期末考试试题及答案提供了全面的学习和复习指南,帮助学生理解和掌握Java编程的核心...
《Java语言程序设计进阶篇(第5版)》是一本深入探讨Java编程技术的权威教材,适合已经掌握Java基础的开发者进一步提升技能。这本书的源代码提供了丰富的实例,涵盖了多线程、网络编程、I/O流、集合框架、异常处理、...