
Java反射机制详解
1 反射机制是什么
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
2 反射机制能做什么
反射机制主要提供了以下功能:
在运行时判断任意一个对象所属的类;
在运行时构造任意一个类的对象;
在运行时判断任意一个类所具有的成员变量和方法;
在运行时调用任意一个对象的方法;
生成动态代理。
3 反射机制的相关API
通过一个对象获得完整的包名和类名
package netxsoftlabbaike;public class TestReflect {
public static void main(String[] args) throws Exception {
TestReflect testReflect = new TestReflect();
Systemoutprintln(testReflectgetClass()getName());
// 结果 netxsoftlabbaikeTestReflect
}
}
实例化Class类对象
package netxsoftlabbaike;public class TestReflect {
public static void main(String[] args) throws Exception {
Class<> class1 = null;
Class<> class2 = null;
Class<> class3 = null;
// 一般采用这种形式
class1 = ClassforName("netxsoftlabbaikeTestReflect");
class2 = new TestReflect()getClass();
class3 = TestReflectclass;
Systemoutprintln("类名称 " + class1getName());
Systemoutprintln("类名称 " + class2getName());
Systemoutprintln("类名称 " + class3getName());
}
}
获取一个对象的父类与实现的接口
package netxsoftlabbaike;import javaioSerializable;
public class TestReflect implements Serializable {
private static final long serialVersionUID = -2862585049955236662L;
public static void main(String[] args) throws Exception {
Class<> clazz = ClassforName("netxsoftlabbaikeTestReflect");
// 取得父类
Class<> parentClass = clazzgetSuperclass();
Systemoutprintln("clazz的父类为:" + parentClassgetName());
// clazz的父类为: javalangObject
// 获取所有的接口
Class<> intes[] = clazzgetInterfaces();
Systemoutprintln("clazz实现的接口有:");
for (int i = 0; i < inteslength; i++) {
Systemoutprintln((i + 1) + ":" + intes[i]getName());
}
// clazz实现的接口有:
// 1:javaioSerializable
}
}
获取某个类中的全部构造函数 - 详见下例
通过反射机制实例化一个类的对象
package netxsoftlabbaike;import javalangreflectConstructor;
public class TestReflect {
public static void main(String[] args) throws Exception {
Class<> class1 = null;
class1 = ClassforName("netxsoftlabbaikeUser");
// 第一种方法,实例化默认构造方法,调用set赋值
User user = (User) class1newInstance();
usersetAge(20);
usersetName("Rollen");
Systemoutprintln(user);
// 结果 User [age=20, name=Rollen]
// 第二种方法 取得全部的构造函数 使用构造函数赋值
Constructor<> cons[] = class1getConstructors();
// 查看每个构造方法需要的参数
for (int i = 0; i < conslength; i++) {
Class<> clazzs[] = cons[i]getParameterTypes();
Systemoutprint("cons[" + i + "] (");
for (int j = 0; j < clazzslength; j++) {
if (j == clazzslength - 1)
Systemoutprint(clazzs[j]getName());
else
Systemoutprint(clazzs[j]getName() + ",");
}
Systemoutprintln(")");
}
// 结果
// cons[0] (javalangString)
// cons[1] (int,javalangString)
// cons[2] ()
user = (User) cons[0]newInstance("Rollen");
Systemoutprintln(user);
// 结果 User [age=0, name=Rollen]
user = (User) cons[1]newInstance(20, "Rollen");
Systemoutprintln(user);
// 结果 User [age=20, name=Rollen]
}
}
class User {
private int age;
private String name;
public User() {
super();
}
public User(String name) {
super();
thisname = name;
}
public User(int age, String name) {
super();
thisage = age;
thisname = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
thisage = age;
}
public String getName() {
return name;
}
public void setName(String name) {
thisname = name;
}
@Override
public String toString() {
return "User [age=" + age + ", name=" + name + "]";
}
}
获取某个类的全部属性
package netxsoftlabbaike;import javaioSerializable;
import javalangreflectField;
import javalangreflectModifier;
public class TestReflect implements Serializable {
private static final long serialVersionUID = -2862585049955236662L;
public static void main(String[] args) throws Exception {
Class<> clazz = ClassforName("netxsoftlabbaikeTestReflect");
Systemoutprintln("===============本类属性===============");
// 取得本类的全部属性
Field[] field = clazzgetDeclaredFields();
for (int i = 0; i < fieldlength; i++) {
// 权限修饰符
int mo = field[i]getModifiers();
String priv = ModifiertoString(mo);
// 属性类型
Class<> type = field[i]getType();
Systemoutprintln(priv + " " + typegetName() + " " + field[i]getName() + ";");
}
Systemoutprintln("==========实现的接口或者父类的属性==========");
// 取得实现的接口或者父类的属性
Field[] filed1 = clazzgetFields();
for (int j = 0; j < filed1length; j++) {
// 权限修饰符
int mo = filed1[j]getModifiers();
String priv = ModifiertoString(mo);
// 属性类型
Class<> type = filed1[j]getType();
Systemoutprintln(priv + " " + typegetName() + " " + filed1[j]getName() + ";");
}
}
}
通过反射机制调用某个类的方法
package netxsoftlabbaike;import javalangreflectMethod;
public class TestReflect {
public static void main(String[] args) throws Exception {
Class<> clazz = ClassforName("netxsoftlabbaikeTestReflect");
// 调用TestReflect类中的reflect1方法
Method method = clazzgetMethod("reflect1");
methodinvoke(clazznewInstance());
// Java 反射机制 - 调用某个类的方法1
// 调用TestReflect的reflect2方法
method = clazzgetMethod("reflect2", intclass, Stringclass);
methodinvoke(clazznewInstance(), 20, "张三");
// Java 反射机制 - 调用某个类的方法2
// age -> 20 name -> 张三
}
public void reflect1() {
Systemoutprintln("Java 反射机制 - 调用某个类的方法1");
}
public void reflect2(int age, String name) {
Systemoutprintln("Java 反射机制 - 调用某个类的方法2");
Systemoutprintln("age -> " + age + " name -> " + name);
}
}
通过反射机制 *** 作某个类的属性
package netxsoftlabbaike;import javalangreflectField;
public class TestReflect {
private String proprety = null;
public static void main(String[] args) throws Exception {
Class<> clazz = ClassforName("netxsoftlabbaikeTestReflect");
Object obj = clazznewInstance();
// 可以直接对 private 的属性赋值
Field field = clazzgetDeclaredField("proprety");
fieldsetAccessible(true);
fieldset(obj, "Java反射机制");
Systemoutprintln(fieldget(obj));
}
}
4 反射机制的应用实例
在泛型为Integer的ArrayList中存放一个String类型的对象。
package netxsoftlabbaike;import javalangreflectMethod;
import javautilArrayList;
public class TestReflect {
public static void main(String[] args) throws Exception {
ArrayList<Integer> list = new ArrayList<Integer>();
Method method = listgetClass()getMethod("add", Objectclass);
methodinvoke(list, "Java反射机制实例。");
Systemoutprintln(listget(0));
}
}
通过反射取得并修改数组的信息
package netxsoftlabbaike;import javalangreflectArray;
public class TestReflect {
public static void main(String[] args) throws Exception {
int[] temp = { 1, 2, 3, 4, 5 };
Class<> demo = tempgetClass()getComponentType();
Systemoutprintln("数组类型: " + demogetName());
Systemoutprintln("数组长度 " + ArraygetLength(temp));
Systemoutprintln("数组的第一个元素: " + Arrayget(temp, 0));
Arrayset(temp, 0, 100);
Systemoutprintln("修改之后数组第一个元素为: " + Arrayget(temp, 0));
}
}
将反射机制应用于工厂模式
package netxsoftlabbaike;interface fruit {
public abstract void eat();
}
class Apple implements fruit {
public void eat() {
Systemoutprintln("Apple");
}
}
class Orange implements fruit {
public void eat() {
Systemoutprintln("Orange");
}
}
class Factory {
public static fruit getInstance(String ClassName) {
fruit f = null;
try {
f = (fruit) ClassforName(ClassName)newInstance();
} catch (Exception e) {
eprintStackTrace();
}
return f;
}
}
/
对于普通的工厂模式当我们在添加一个子类的时候,就需要对应的修改工厂类。 当我们添加很多的子类的时候,会很麻烦。
Java 工厂模式可以参考
>}我有一个微信公众号,经常会分享一些Java技术相关的干货,还有一些学习资源。
如果你喜欢我的分享,可以用微信搜索“Java团长”或者“javatuanzhang”关注。
可以的,下面是说明。
<T> where T : 类型约束
T:结构
类型参数必须是值类型。可以指定除 Nullable 以外的任何值类型。有关更多信息,请参见使用可空类型(C# 编程指南)。
T:类
类型参数必须是引用类型,包括任何类、接口、委托或数组类型。
T:new()
类型参数必须具有无参数的公共构造函数。当与其他约束一起使用时,new() 约束必须最后指定。
T:<基类名>
类型参数必须是指定的基类或派生自指定的基类。
T:<接口名称>
类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。约束接口也可以是泛型的。
T:U
为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。这称为裸类型约束。
msdn中的例子:
public class Employee
{
private string name;
private int id;
public Employee(string s, int i)
{
name = s;
id = i;
}
public string Name
{
get { return name; }
set { name = value; }
}
public int ID
{
get { return id; }
set { id = value; }
}
}
public class GenericList<T> where T : Employee
{
private class Node
{
private Node next;
private T data;
public Node(T t)
{
next = null;
data = t;
}
public Node Next
{
get { return next; }
set { next = value; }
}
public T Data
{
get { return data; }
set { data = value; }
}
}
private Node head;
public GenericList() //constructor
{
head = null;
}
public void AddHead(T t)
{
Node n = new Node(t);
nNext = head;
head = n;
}
public IEnumerator<T> GetEnumerator()
{
Node current = head;
while (current != null)
{
yield return currentData;
current = currentNext;
}
}
public T FindFirstOccurrence(string s)
{
Node current = head;
T t = null;
while (current != null)
{
//The constraint enables access to the Name property
if (currentDataName == s)
{
t = currentData;
break;
}
else
{
current = currentNext;
}
}
return t;
}
}
用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。
Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。
以下示例使用 Class 对象来显示对象的类名:
void printClassName(Object obj) {
Systemoutprintln("The class of " + obj +
" is " + objgetClass()getName());
}
还可以使用一个类字面值来获得命名类型(或 void)的 Class 对象。例如:
Systemoutprintln("The name of class Foo is: "+FooclassgetName());
aaget( 你的索引 )getClass() 实际上,这个就相当于MainFormListclass
这样就获取到了你所get出来的元素的 泛型类型 了,
大多是反射的时候在需要获取。。。
希望可以帮助到你
一、什么是反射:
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。其中LEAD/LEAD++ 、OpenC++ 、MetaXa和OpenJava等就是基于反射机制的语言。最近,反射机制也被应用到了视窗系统、 *** 作系统和文件系统中。反射本身并不是一个新概念,尽管计算机科学赋予了反射概念新的含义。在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。二、什么是Java中的类反射:
Reflection 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说“自审”,并能直接 *** 作程序的内部属性和方法。Java 的这一能力在实际应用中用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性。例如,Pascal、C 或者 C++ 中就没有办法在程序中获得函数定义相关的信息。
Reflection 是 Java 被视为动态(或准动态)语言的关键,允许程序于执行期 Reflection APIs 取得任何已知名称之 class 的内部信息,包括 package、type parameters、superclass、implemented interfaces、inner classes, outer class, fields、constructors、methods、modifiers,并可于执行期生成instances、变更 fields 内容或唤起 methods。三、Java类反射中所必须的类:
Java的类反射所需要的类并不多,它们分别是:Field、Constructor、Method、Class、Object,下面我将对这些类做一个简单的说明。
Field类:提供有关类或接口的属性的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)属性或实例属性,简单的理解可以把它看成一个封装反射类的属性的类。
Constructor类:提供关于类的单个构造方法的信息以及对它的访问权限。这个类和Field类不同,Field类封装了反射类的属性,而Constructor类则封装了反射类的构造方法。
Method类:提供关于类或接口上单独某个方法的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。 这个类不难理解,它是用来封装反射类方法的一个类。
Class类:类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。
Object类:每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。四、Java的反射类能做什么:
看完上面的这么多我想你已经不耐烦了,你以为我在浪费你的时间,那么好吧!下面我们就用一些简单的小例子来说明它。
首先我们来看一下通过Java的反射机制我们能得到些什么。
首先我们来写一个类:java 代码
import javaawteventActionListener;
import javaawteventActionEvent;
class A extends Object implements ActionListener{
private int a = 3;
public Integer b = new Integer(4);
public A(){}
public A(int id,String name){}
public int abc(int id,String name){return 0;}
public void actionPerformed(ActionEvent e){}
} 你可能被我这个类弄糊涂了,你看不出我要做什么,那就不要看这个类了,这个类是用来测试的,你知道知道它继承了Object类,有一个接口是ActionListener,两个属性int和Integer,两个构造方法和两个方法,这就足够了。
下面我们把A这个类作为一个反射类,来过去A类中的一些信息,首先我们先来过去一下反射类中的属性和属性值。java 代码
import javalangreflect;
class B{
public static void main(String args[]){
A r = new A();
Class temp = rgetClass();
try{
Systemoutprintln("反射类中所有公有的属性");
Field[] fb =tempgetFields();
for(int j=0;j<fblength;j++){
Class cl = fb[j]getType();
Systemoutprintln("fb:"+cl);
}
Systemoutprintln("反射类中所有的属性");
Field[] fa = tempgetDeclaredFields();
for(int j=0;j<falength;j++){
Class cl = fa[j]getType();
Systemoutprintln("fa:"+cl);
}
Systemoutprintln("反射类中私有属性的值");
Field f = tempgetDeclaredField("a");
fsetAccessible(true);
Integer i = (Integer)fget(r);
Systemoutprintln(i);
}catch(Exception e){
eprintStackTrace();
}
}
} 这里用到了两个方法,getFields()、getDeclaredFields(),它们分别是用来获取反射类中所有公有属性和反射类中所有的属性的方法。另外还有getField(String)和getDeclaredField(String)方法都是用来过去反射类中指定的属性的方法,要注意的是getField方法只能取到反射类中公有的属性,而getDeclaredField方法都能取到。
这里还用到了Field 类的setAccessible方法,它是用来设置是否有权限访问反射类中的私有属性的,只有设置为true时才可以访问,默认为false。另外 Field类还有set(Object AttributeName,Object value)方法,可以改变指定属性的值。下面我们来看一下如何获取反射类中的构造方法java 代码
import javalangreflect;
public class SampleConstructor {
public static void main(String[] args) {
A r = new A();
printConstructors(r);
}
public static void printConstructors(A r) {
Class c = rgetClass();
//获取指定类的类名
String className = cgetName();
try {
//获取指定类的构造方法
Constructor[] theConstructors = cgetConstructors();
for(int i=0; i<theConstructorslength; i++) {
//获取指定构造方法的参数的集合
Class[] parameterTypes = theConstructors[i]getParameterTypes();
Systemoutprint(className + "(");
for(int j=0; j<parameterTypeslength; j++)
Systemoutprint(parameterTypes[j]getName() + " ");
Systemoutprintln(")");
}
}catch(Exception e) {
eprintStackTrace();
}
}
}
这个例子很简单,只是用getConstructors()方法获取了反射类的构造方法的集合,并用Constructor类的getParameterTypes()获取该构造方法的参数。下面我们再来获取一下反射类的父类(超类)和接口java 代码
import javaio;
import javalangreflect;
public class SampleInterface {
public static void main(String[] args) throws Exception {
A raf = new A();
printInterfaceNames(raf);
}
public static void printInterfaceNames(Object o) {
Class c = ogetClass();
//获取反射类的接口
Class[] theInterfaces = cgetInterfaces();
for(int i=0; i<theInterfaceslength; i++)
Systemoutprintln(theInterfaces[i]getName());
//获取反射类的父类(超类)
Class theSuperclass = cgetSuperclass();
Systemoutprintln(theSuperclassgetName());
}
} 这个例子也很简单,只是用Class类的getInterfaces()方法获取反射类的所有接口,由于接口可以有多个,所以它返回一个 Class数组。用getSuperclass()方法来获取反射类的父类(超类),由于一个类只能继承自一个类,所以它返回一个Class对象。下面我们来获取一下反射类的方法java 代码
import javalangreflect;
public class SampleMethod {
public static void main(String[] args) {
A p = new A();
printMethods(p);
}
public static void printMethods(Object o) {
Class c = ogetClass();
String className = cgetName();
Method[] m = cgetMethods();
for(int i=0; i<mlength; i++) {
//输出方法的返回类型
Systemoutprint(m[i]getReturnType()getName());
//输出方法名
Systemoutprint(" "+m[i]getName()+"(");
//获取方法的参数
Class[] parameterTypes = m[i]getParameterTypes();
for(int j=0; j<parameterTypeslength; j++){
Systemoutprint(parameterTypes[j]getName());
if(parameterTypeslength>j+1){
Systemoutprint(",");
}
}
Systemoutprintln(")");
}
}
} 这个例子并不难,它只是获得了反射类的所有方法,包括继承自它父类的方法。然后获取方法的返回类型、方法名和方法参数。接下来让我们回过头来想一想,我们获取了反射类的属性、构造方法、父类、接口和方法,可这些东西能帮我们做些什么呢!!
下面我写一个比较完整的小例子,来说明Java的反射类能做些什么吧!!java 代码
import javalangreflectConstructor;
import javalangreflectMethod;
public class LoadMethod {
public Object Load(String cName,String MethodName,String[] type,String[] param){
Object retobj = null;
try {
//加载指定的Java类
Class cls = ClassforName(cName);
//获取指定对象的实例
Constructor ct = clsgetConstructor(null);
Object obj = ctnewInstance(null);
//构建方法参数的数据类型
Class partypes[] = thisgetMethodClass(type);
//在指定类中获取指定的方法
Method meth = clsgetMethod(MethodName, partypes);
//构建方法的参数值
Object arglist[] = thisgetMethodObject(type,param);
//调用指定的方法并获取返回值为Object类型
retobj= methinvoke(obj, arglist);
}
catch (Throwable e) {
Systemerrprintln(e);
}
return retobj;
}
//获取参数类型Class[]的方法
public Class[] getMethodClass(String[] type){
Class[] cs = new Class[typelength];
for (int i = 0; i < cslength; i++) {
if(!type[i]trim()equals("")||type[i]!=null){
if(type[i]equals("int")||type[i]equals("Integer")){
cs[i]=IntegerTYPE;
}else if(type[i]equals("float")||type[i]equals("Float")){
cs[i]=FloatTYPE;
}else if(type[i]equals("double")||type[i]equals("Double")){
cs[i]=DoubleTYPE;
}else if(type[i]equals("boolean")||type[i]equals("Boolean")){
cs[i]=BooleanTYPE;
}else{
cs[i]=Stringclass;
}
}
}
return cs;
}
//获取参数Object[]的方法
public Object[] getMethodObject(String[] type,String[] param){
Object[] obj = new Object[paramlength];
for (int i = 0; i < objlength; i++) {
if(!param[i]trim()equals("")||param[i]!=null){
if(type[i]equals("int")||type[i]equals("Integer")){
obj[i]= new Integer(param[i]);
}else if(type[i]equals("float")||type[i]equals("Float")){
obj[i]= new Float(param[i]);
}else if(type[i]equals("double")||type[i]equals("Double")){
obj[i]= new Double(param[i]);
}else if(type[i]equals("boolean")||type[i]equals("Boolean")){
obj[i]=new Boolean(param[i]);
}else{
obj[i] = param[i];
}
}
}
return obj;
}
} 这是我在工作中写的一个实现Java在运行时加载指定的类,并调用指定方法的一个小例子。这里没有main方法,你可以自己写一个。
Load方法接收的五个参数分别是,Java的类名,方法名,参数的类型和参数的值。结束语:
Java语言反射提供一种动态链接程序组件的多功能方法。它允许程序创建和控制任何类的对象,无需提前硬编码目标类。这些特性使得反射特别适用于创建以非常普通的方式与对象协作的库。Java reflection 非常有用,它使类和数据结构能按名称动态检索相关信息,并允许在运行着的程序中 *** 作这些信息。Java 的这一特性非常强大,并且是其它一些常用语言,如 C、C++、Fortran 或者 Pascal 等都不具备的。但反射有两个缺点。第一个是性能问题。用于字段和方法接入时反射要远慢于直接代码。性能问题的程度取决于程序中是如何使用反射的。如果它作为程序运行中相对很少涉及的部分,缓慢的性能将不会是一个问题。即使测试中最坏情况下的计时图显示的反射 *** 作只耗用几微秒。仅反射在性能关键的应用的核心逻辑中使用时性能问题才变得至关重要。
JAVA中Resultset是一个类 而不是一个方法。记住啊。
结果集(ResultSet)是数据中查询结果返回的一种对象,可以说结果集是一个存储查询结果的对象,但是结果集并不仅仅具有存储的功能,他同时还具有 *** 纵数据的功能,可能完成对数据的更新等。
结果集读取数据的方法主要是getXXX(),它的参数可以是整型,表示第几列(是从1开始的),还可以是列名。返回的是对应的XXX类型的值。如果对应那列时空值,XXX是对象的话返回XXX型的空值,如果XXX是数字类型,如Float等则返回0,boolean返回false。使用getString()可以返回所有的列的值,不过返回的都是字符串类型的。XXX可以代表的类型有:基本的数据类型如整型(int),布尔型(Boolean),浮点型(Float,Double)等,比特型(byte),还包括一些特殊的类型,如:日期类型(javasqlDate),时间类型(javasqlTime),时间戳类型(javasqlTimestamp),大数型(BigDecimal和BigInteger等)等。还可以使用getArray(int colindex/String columnname),通过这个方法获得当前行中,colindex所在列的元素组成的对象的数组。使用getAsciiStream(
int colindex/String colname)可以获得该列对应的当前行的ascii流。也就是说所有的getXXX方法都是对当前行进行 *** 作。
结果集从其使用的特点上可以分为四类,这四类的结果集的所具备的特点都是和Statement语句的创建有关,因为结果集是通过Statement语句执行后产生的,所以可以说,结果集具备何种特点,完全决定于Statement,当然我是说下面要将的四个特点,在Statement创建时包括三种类型。首先是无参数类型的,他对应的就是下面要介绍的基本的ResultSet对应的Statement。下面的代码中用到的Connection并没有对其初始化,变量conn代表的就是Connection对应的对象。SqlStr代表的是响应的SQL语句。
1、 最基本的ResultSet。
之所以说是最基本的ResultSet是因为,这个ResultSet他起到的作用就是完成了查询结果的存储功能,而且只能读去一次,不能够来回的滚动读取。这种结果集的创建方式如下:
Statement st = connCreateStatement
ResultSet rs = StatementexcuteQuery(sqlStr);
由于这种结果集不支持,滚动的读去功能所以,如果获得这样一个结果集,只能使用它里面的next()方法,逐个的读去数据。
2 可滚动的ResultSet类型。
这个类型支持前后滚动取得纪录next()、previous(),回到第一行first(),同时还支持要去的ResultSet中的第几行absolute(int n),以及移动到相对当前行的第几行relative(int n),要实现这样的ResultSet在创建Statement时用如下的方法。
Statement st = conncreateStatement(int resultSetType, int resultSetConcurrency)
ResultSet rs = stexecuteQuery(sqlStr)
其中两个参数的意义是:
resultSetType是设置ResultSet对象的类型可滚动,或者是不可滚动。取值如下:
ResultSetTYPE_FORWARD_ONLY只能向前滚动
ResultSetTYPE_SCROLL_INSENSITIVE和ResultTYPE_SCROLL_SENSITIVE这两个方法都能够实现任意的前后滚动,使用各种移动的ResultSet指针的方法。二者的区别在于前者对于修改不敏感,而后者对于修改敏感。
resultSetConcurency是设置ResultSet对象能够修改的,取值如下:
ResultSetCONCUR_READ_ONLY 设置为只读类型的参数。
ResultSetCONCUR_UPDATABLE 设置为可修改类型的参数。
所以如果只是想要可以滚动的类型的Result只要把Statement如下赋值就行了。
Statement st = conncreateStatement(ResultTYPE_SCROLL_INSENITIVE,
ResultSetCONCUR_READ_ONLY);
ResultSet rs = stexcuteQuery(sqlStr);
用这个Statement执行的查询语句得到的就是可滚动的ResultSet。
3、 可更新的ResultSet
这样的ResultSet对象可以完成对数据库中表的修改,但是我知道ResultSet只是相当于数据库中表的视图,所以并不时所有的ResultSet只要设置了可更新就能够完成更新的,能够完成更新的ResultSet的SQL语句必须要具备如下的属性:
a、只引用了单个表。
b、不含有join或者group by子句。
c、那些列中要包含主关键字。
具有上述条件的,可更新的ResultSet可以完成对数据的修改,可更新的结果集的创建方法是:
Statement st = createstatement(ResultTYPE_SCROLL_INSENSITIVE,ResultCONCUR_UPDATABLE)
4、 可保持的ResultSet
正常情况下如果使用Statement执行完一个查询,又去执行另一个查询时这时候第一个查询的结果集就会被关闭,也就是说,所有的Statement的查询对应的结果集是一个,如果调用Connection的commit()方法也会关闭结果集。可保持性就是指当ResultSet的结果被提交时,是被关闭还是不被关闭。JDBC20和10提供的都是提交后ResultSet就会被关闭。不过在JDBC30中,我们可以设置ResultSet是否关闭。要完成这样的ResultSet的对象的创建,要使用的Statement的创建要具有三个参数,这个Statement的创建方式也就是,我所说的Statement的第三种创建方式。如下:
Statement st=createStatement(int resultsetscrollable,int resultsetupdateable,int resultsetSetHoldability)
ResultSet rs = stexcuteQuery(sqlStr);
前两个参数和两个参数的createStatement方法中的参数是完全相同的,这里只介绍第三个参数:
resultSetHoldability表示在结果集提交后结果集是否打开,取值有两个:
ResultSetHOLD_CURSORS_OVER_COMMIT:表示修改提交时,不关闭数据库。
ResultSetCLOSE_CURSORS_AT_COMMIT:表示修改提交时ResultSet关闭。
以上就是关于java中的反射机制是什么有什么作用呢求解,谢谢。全部的内容,包括:java中的反射机制是什么有什么作用呢求解,谢谢。、有关泛型、Java 反射等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)