我一直觉得Hibernate在做数据库查询的时候,是运用JAVA反射机制创建POJO对象,然后运用POJO的SET()方法把POJO的各个属性值设为数据库查询返回所对应的值,最后返回这个对象。但是为什么我把POJO的setId()方法设为private,然后做数据库查询的时候,Hibernate仍可以返回这个POJO的ID属性值的?它是在调用private的setId()方法吗?是不是Hibernate在动态代理中做了手脚啊?
以下是我的POJO类代码:
[code="java"]
public class Student {
private int student_id;
private String student_name;
private int student_age;
public int getStudent_id()
{
return student_id;
}
public String getStudent_name()
{
return student_name;
}
public int getStudent_age()
{
return student_age;
}
private void setStudent_id(int id)
{
this.student_id = id;
}
public void setStudent_name(String name)
{
this.student_name = name;
}
public void setStudent_age(int age)
{
this.student_age = age;
}
}[/code]
[b]问题补充:[/b]
是的public Field[] getDeclaredFields()可以找出类的所有成员变量,包括私有变量。但是它不能将私有变量赋值,否则违反了java的封装。Hibernate通过什么方法可以把私有成员变量赋值成数据库查询到的值然后返回POJO对象呢?动态代理?
但是它不能将私有变量赋值,否则违反了java的封装
谁告诉你它不能将私有变量赋值??
setAccessible
public void setAccessible(boolean flag)
throws SecurityException将此对象的 accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false 则指示反射的对象应该实施 Java 语言访问检查。
反射可以用方法也可以用字段的反射
Class
getDeclaredFields
public Field[] getDeclaredFields()
throws SecurityException返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段,包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段。返回数组中的元素没有排序,也没有任何特定的顺序。如果该类或接口不声明任何字段,或者此 Class 对象表示一个基本类型、一个数组类或 void,则此方法返回一个长度为 0 的数组。
Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。
给你看个例子吧
[code="java"]
import java.lang.reflect.Field;
public class ReflectTest {
/**
* @param args
* @throws NoSuchFieldException
* @throws SecurityException
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
PrivateClass p= new PrivateClass();
Field i = PrivateClass.class.getDeclaredField("i");
Field j = PrivateClass.class.getDeclaredField("j");
i.setAccessible(true);
i.setInt(p, 1);
j.setAccessible(true);
j.setInt(p, 2);
System.out.println(p);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class PrivateClass
{
@Override
public String toString() {
// TODO Auto-generated method stub
return "i=" + i + ",j=" + j;
}
private int i;
private int j;
}
[/code]
反射机制
不受 private public等可见修饰符的影响。
反射机制 java的一大特性。抛开业务开发。
在开发工具性质的代码中,一定会用到。