- 浏览: 409287 次
- 性别:
- 来自: 秦皇岛
最新评论
-
prayjourney:
了解了,讲的不错
DataInputStream和DataOutputStream类 -
niunianss:
将字节退回的时候,需要添加判断,最后一个字符是英文时,实际数组 ...
PushbackInputStream -
cctt_1:
不要误人子弟,那根本就不是 解释器模式!!!那是Composi ...
Interpreter(解释器)模式 -
java-大神:
[i][i]引用引用引用引用[/img][/img][/img ...
BufferedReader和BufferedWriter -
百合不是茶:
你的程序在文件输入输出流中传入agrs[0]时,会报错越界 ...
DataInputStream和DataOutputStream类
1. 修改成员值:
尽管直接存取类的域成员是不被鼓励的,但仍可以直接存取公开的域成员,甚至也可以通过反射机制来存取私有域成员。下面以一个实例来说明,首先编写一个TestField类。
package ysu.hxy; public class TestField { public int testInt; public String testString; public String toString() { return testInt + ":" +testString; } }
下面的范例利用反射机制动态加载类来存取域成员:
package ysu.hxy; import java.lang.reflect.Field; public class AssignFieldDemo { public static void main(String[] args) { try { Class c = Class.forName(args[0]); Object targetObj = c.newInstance(); //返回域成员 Field testInt = c.getField("testInt"); testInt.setInt(targetObj,99); Field testString = c.getField("testString"); testString.set(targetObj,"caterpillar"); System.out.println(targetObj); } catch(ArrayIndexOutOfBoundsException e) { System.out.println("没有指定类"); } catch(ClassNotFoundException e) { System.out.println("找不到指定的类"); } catch(SecurityException e) { e.printStackTrace(); } catch(NoSuchFieldException e) { System.out.println("找不到指定的域成员"); } catch(InstantiationException e) { e.printStackTrace(); } catch(IllegalAccessException e) { e.printStackTrace(); } } }
运行结果:
D:\hxy>java ysu.hxy.AssignFieldDemo ysu.hxy.TestField
99:caterpillar
如果有必要,也可以通过反射机制存取私有的域成员,如:
Field privateField = c.getDeclaredField("privateField"); privateField.setAccessible(true); privateField.setInt(targetObj,99);
2.再看数组对象:
在Java中数组也是一个对象,也会有一个Class实例来表示它。如下:
package ysu.hxy; public class ArrayDemo { public static void main(String[] args) { short[] sArr = new short[5]; int[] iArr = new int[5]; long[] lArr = new long[5]; float[] fArr = new float[5]; double[] dArr = new double[5]; byte[] bArr = new byte[5]; boolean[] zArr = new boolean[5]; String[] strArr = new String[5]; System.out.println("short 数组类:" + sArr.getClass()); System.out.println("int 数组类:" + iArr.getClass()); System.out.println("long 数组类:" + lArr.getClass()); System.out.println("float 数组类:" + fArr.getClass()); System.out.println("double 数组类:" + dArr.getClass()); System.out.println("byte 数组类:" + bArr.getClass()); System.out.println("boolean 数组类:" + zArr.getClass()); System.out.println("String 数组类:" + strArr.getClass()); } }
运行结果:
D:\hxy>java ysu.hxy.ArrayDemo
short 数组类:class [S
int 数组类:class [I
long 数组类:class [J
float 数组类:class [F
double 数组类:class [D
byte 数组类:class [B
boolean 数组类:class [Z
String 数组类:class [Ljava.lang.String;
若要使用反射机制动态生成数组,可以使用java.lang.reflect.Array来协助。下面的这个范例示范了如何生成String数组:
package ysu.hxy; import java.lang.reflect.Array; public class NewArrayDemo { public static void main(String[] args) { Class c = String.class; Object objArr = Array.newInstance(c,5); for(int i = 0;i < 5;i++) { Array.set(objArr,i,i+""); } for(int i = 0;i < 5;i++) { System.out.print(Array.get(objArr,i) + " "); } System.out.println(); String[] strs = (String[]) objArr; for(String s : strs) { System.out.print(s+ " "); } } }
Array.newInstance()的第一个参数指定元素类型,而第二个参数指定数组长度。此方法还有另一个版本,用于创建二维数组,如下:
package onlyfun.caterpillar; import java.lang.reflect.Array; public class NewArrayDemo2 { public static void main(String[] args) { Class c = String.class; // 打算建立一个3*4数组 int[] dim = new int[]{3, 4}; Object objArr = Array.newInstance(c, dim); for(int i = 0; i < 3; i++) { Object row = Array.get(objArr, i); for(int j = 0; j < 4; j++) { Array.set(row, j, "" + (i+1)*(j+1)); } } for(int i = 0; i < 3; i++) { Object row = Array.get(objArr, i); for(int j = 0; j < 4; j++) { System.out.print(Array.get(row, j) + " "); } System.out.println(); } } }
如果要得知数组元素的类型,可以在取得数组的Class实例之后,使用Class实例的getComponentType()方法,所取回的是元素的Class实例。例如:
int[] iArr = new int[5]; System.out.println(iArr.getClass().getComponentType());
3. Proxy类:
java.lang.reflect.Proxy类,可协助实现动态代理功能。例如:假设打算开发一个HelloSpeaker类,其中有一个hello()方法,想要在这个hello()调用前后加上记录的功能,但又不想将记录的功能写到HelloSpeaker类中。这时可以使用Proxy类来实现动态代理。
要实现动态代理,首先要定义所要代理的接口。如下定义了有hello()方法的IHello接口。
package ysu.hxy; public interface IHello { public void hello(String name); }
HelloSpeaker类实现了IHello接口,如下:
package ysu.hxy; public class HelloSpeaker implements IHello { public void hello(String name) { System.out.println("Hello," + name); } }
可以实现一个处理记录的处理器(Handler),让处理器在调用hello()方法的前后进行记录的动作。一个处理器必须实现java.lang.reflect.InvocationHandler接口,InvocationHandler有一个invoke()方法必须实现。
package ysu.hxy; import java.util.logging.*; import java.lang.reflect.*; public class LogHandler implements InvocationHandler { private Logger logger = Logger.getLogger(this.getClass().getName()); private Object delegate; //绑定要代理的对象 public Object bind(Object delegate) { this.delegate = delegate; //建立并返回代理对象 return Proxy.newProxyInstance( delegate.getClass().getClassLoader(), //要被代理的接口 delegate.getClass().getInterfaces(), this); } //代理要调用的方法,并在其前后增加行为 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; try { logger.log(Level.INFO,"method starts..." + method.getName()); result = method.invoke(delegate,args); logger.log(Level.INFO,"method endss..." + method.getName()); } catch(Exception e) { logger.log(Level.INFO,e.toString()); } return result; } }
主要的概念是使用Proxy.newProxyInstance()方法建立一个代理对象,建立代理对象时必须告知所要代理的操作接口,然后可以操作所建立的代理对象,在每次操作时会调用InvocationHandler的invoke()方法,invoke()方法会传入被代理对象的方法名称与运行变量,实际上要运行的方法交由method.invoke()。在method.invoke()前后加上记录动作,method.invoke()返回的对象是实际方法运行后的回传结果。先来看看一个运行的例子:
package ysu.hxy; public class ProxyDemo { public static void main(String[] args) { LogHandler handler = new LogHandler(); IHello speaker = new HelloSpeaker(); //代理speaker的对象 IHello speakerProxy = (IHello)handler.bind(speaker); speakerProxy.hello("Justin"); } }
运行结果:
D:\hxy>java ysu.hxy.ProxyDemo
2009-4-6 19:06:24 ysu.hxy.LogHandler invoke
信息: method starts...hello
Hello,Justin
2009-4-6 19:06:24 ysu.hxy.LogHandler invoke
信息: method endss...hello
通过代理机制,在不将记录动作写入HelloSpeaker类程序代码的情况下,可以为其加入记录的功能。这只是在hello()方法前后由代理对象speakerProxy先执行记录功能而已,真正运行hello()方法时才使用speaker对象。
发表评论
-
内部类总结
2009-11-27 14:28 1222一、方法及作用域内的内部类:1.在一个方法内定义的类2.在一个 ... -
finalize()方法终结条件验证 示例代码
2009-09-20 09:23 1348package Initialization; clas ... -
Proxy(代理)模式二
2009-05-15 21:16 15532. 重新思考图像代理: 现在需要思考设计模式是否 ... -
Junit简介
2009-04-08 17:46 16501. 单元测试(Unit Test) 一个单元(Un ... -
Ant简介
2009-04-08 13:10 18531. Ant可以自动完成的任务: (1)编译Java源代 ... -
专题制作--文字编辑器(文字编辑与保存)
2009-04-08 10:43 22161. 文字编辑与保存: (1). 打开文件的处理流 ... -
专题制作--文字编辑器(逻辑实现部分)
2009-04-07 22:35 19061. 事件处理: 在Java中事件以具体的对象来表 ... -
专题制作--文字编辑器(接口部分)
2009-04-07 20:28 21501. Swing入门: 若要使用J2SE来开发窗口应用 ... -
信息绑定(国际化处理)
2009-04-07 20:02 15851. 程序中的一些文字信息可以将之定义在一个属性文件中,而不定 ... -
日志(Logging)
2009-04-07 16:14 17291. 日志(Logging) 程序不免会出现错误,当 ... -
Java中的日期和时间
2009-04-07 11:26 19591. 使用Date: 使用System.cu ... -
meta-annotation
2009-04-07 09:23 30831. 所谓meta-annotation就是Annotati ... -
Annotion
2009-04-06 23:05 16841. Annotation对程序运行没有影响,它的目的在于对编 ... -
使用反射生成与操作对象(一)
2009-04-06 15:16 21101. 使用反射机制,可以在运行时期动态加载类并生成对象,操作对 ... -
Java中的反射(二)
2009-04-06 10:42 20781. 当在命令行模式下执行java XXX.class 指令后 ... -
Java中的反射(一)
2009-04-06 09:43 13931. Java提供的反射机制允许您在运行时动态加载类、查看类信 ... -
容器类的线程安全及ThreadLocal类
2009-04-05 21:28 30571. 容器类默认没有考虑 ... -
wait()和notify()
2009-04-05 19:06 13731. wait()、notify()、notifyAll() ... -
Java线程之同步化(Synchronized)主题
2009-04-05 16:44 27151. 如果一个对象所持有的数据可以被多线程同时共享存取,必须 ... -
Java线程(三)
2009-04-05 15:37 18931. Java中的每个线程都 ...
相关推荐
在Java反射JavaBean对象自动生成插入、更新、删除、查询sql语句操作中,主要使用了Java反射机制来获取JavaBean对象的信息,然后根据这些信息生成对应的sql语句。例如,通过Java反射机制可以获取JavaBean对象的成员...
要使用反射创建对象,首先需要获取目标类型的Type对象。这可以通过以下两种方式完成: - 使用`typeof`关键字:`Type myType = typeof(MyClass);` - 使用`Type.GetType()`方法:`Type myType = Type.GetType(...
反射是Java编程语言的一个核心特性,它允许程序在运行时检查、操作类的信息以及创建对象。通过反射,开发者可以实现高度灵活的应用程序,例如框架、插件系统等,其中非常重要的一环就是能够动态地创建对象。本文将...
反射生成SQL实例的核心在于,它允许程序在运行时动态地获取类型信息,并根据这些信息创建和执行SQL语句。以下是一些关键知识点: 1. **反射基础**:C#中的System.Reflection命名空间包含了所有与反射相关的类。其中...
在C#中,利用泛型和反射可以创建灵活的数据库操作库,自动根据实体类生成对应的SQL语句。例如,我们可以定义一个泛型方法,接受一个类型参数,这个类型对应于数据库表的实体模型: ```csharp public void Save(T ...
例如,我们可以创建一个自定义的处理器,该处理器会在编译期间检查带有特定注解的类,并自动生成相应的DAO(数据访问对象)类,这些DAO类已经包含了基于注解信息生成的SQL方法。 总的来说,结合注解和反射,开发者...
Java 使用反射创建并操作对象的方法 Java 的反射机制允许程序在运行时动态地创建和操作对象,这是 Java 程序设计中非常重要的一种技术。下面我们将详细介绍 Java 使用反射创建并操作对象的方法。 反射机制概述 ...
动态代码的使用(反射和动态生成类) 在软件开发中,尤其是在框架和底层开发时,为了更灵活地控制代码,常常需要进行一些动态的操作。动态代码的使用可以分为两大类:反射和动态生成类。 一、反射的使用 反射是...
在编程领域,反射机制是一种强大的特性,允许程序在运行时检查自身的行为,包括类的信息、对象的状态以及函数的调用等。在C++的世界里,Qt框架提供了一种实现反射的手段,即QMetaObject系统。这个系统允许我们动态地...
Hibernate允许开发者将Java对象与数据库表进行映射,通过对象的CRUD(创建、读取、更新、删除)操作实现对数据库的数据操作。在Hibernate中,我们通常使用注解来定义这些映射,比如`@Entity`表示这是一个可持久化的...
现在我们有了一个包含JSON数据的Map,可以开始使用反射来创建对应的Java对象。假设我们有一个User类: ```java public class User { private String name; private int age; // getters and setters } ``` 接...
- **代码生成和编译**:例如,Apache的Velocity和FreeMarker模板引擎使用反射生成运行时代码。 - **元编程**:允许在运行时检查和修改程序的行为。 - **插件系统**:允许加载未知类并执行其方法。 - **序列化和反...
Java反射 JavaBean 对象自动生成插入、更新、删除、查询 SQL 语句操作 Java 反射是 Java 语言中一个强大的功能,它允许开发者在运行时检查和修改类、方法、字段的行为。Java 反射机制可以动态地创建对象、调用方法...
通过反射,我们可以获取类、接口、属性、方法和事件等元数据信息,并在运行时创建和操作对象。在C#中,`System.Reflection`命名空间提供了关于反射所需的所有类和方法。 动态生成控件是指在程序运行时根据需求创建...
在IT行业中,反射查询SQL框架是一种高级编程技术,它结合了面向对象的编程特性与数据库操作,使得开发者可以通过对象和属性来动态构建SQL语句,从而实现对数据库的增、删、改、查(CRUD)操作。这种技术极大地提高了...
Java 反射生成工具_generatorConfig 是一个用于自动化生成Java Bean及Mapper XML文件的实用工具。在Java开发中,反射机制是一种强大的技术,它允许程序在运行时检查和修改类、对象及其属性。generatorConfig则是利用...
要想使用反射,首先需要获得待操作的类所对应的 Class 对象。java.lang.Class 是所有反射 API 的入口点。通过 Class 对象,可以获悉整个类的结构,包括其modifiers、superclass、实现的 interfaces、fields 和 ...
在Java编程中,ORM(Object-Relational Mapping)是一种技术,它允许程序员使用面向对象的方式来操作数据库,将数据库中的表映射为Java对象,而无需编写大量的SQL语句。本主题探讨的是如何通过反射和注解来自定义ORM...
本文将深入探讨如何使用反射机制来操作SQLite数据库,包括插入数据和查询数据,以实现更加灵活和高效的数据库操作。 首先,我们要了解反射的概念。在Java中,反射是一种强大的工具,它允许我们在运行时检查类、接口...
总结起来,Java反射机制提供了一种强大的工具,让我们可以在运行时动态地操作类和对象,这包括调用方法和访问私有字段。但同时,也需要注意其可能带来的副作用。在上述示例中,我们展示了如何利用反射来实现计算器的...