--------------------------------------------------------题记
今天在使用HibernateTemplate的execute方法的时候产生了困惑,即HibernateCallback接口中的doInHibernate方法是如何将Session对象绑定到该线程的Session实例中的,回调函数的原理是什么,匿名内部类的原理是什么?
例如:
List<?> list = getHibernateTemplate().execute(new HibernateCallback(){
public List<?> doInHibernate(Session session) {
List<?> result = session.createQuery(hql);
.setFirstResult(offset)
.setMaxResults(pageSize)
.list();
return result;
}
});
下面只对匿名内部类进行了比较详细的测试,回调函数原理也能看明白,没有太多注解。
-------------------------------------------------------代码(附详细注释)
package anonymous;
/**
*
* 写了一大堆,最后发现匿名内部类需要掌握的有以下几点:
*
* 1.最常用的就是【测试方法6】中使用的方式,与【回调函数】方式结合(已经能看出原理,具体分析略)。
*
* 2.在【匿名内部类】里面【内部定义的成员】,只能在其【内部调用】,除了重写的抽象方法。
*
* 3.匿名内部类返回的引用除了【抽象方法】是使用【重写的方法】(即在内部类中的东西),其他就只能调用其【所属类】的成员了。
*
* 3.使用new运算符后,内部类中【重写的方法】【不能立即地、自动地】执行,需要被调用。
*
* @author Administrator
*
*/
public class Test {
//用于被测试的私有属性
private String name = "name";
//用于被测试的公共属性
public String hello = "hello";
//用于被测试中重写的方法
private void method() {
System.out.println("\n执行【未被重写】的method方法");
}
//=============================================测试方法1
public void testFunction1() {
System.out.println("\n\n==========================测试方法1");
//打印该匿名内部类返回的引用,并且测试其中的方法是否被执行
System.out.println("\n(匿名内部类)返回的对象:"+new Test() {
@SuppressWarnings("unused")
public void method() {
System.out.println("\n执行【重写】的method方法");
}
});
}
//=============================================测试方法2
public void testFunction2() {
System.out.println("\n\n==========================测试方法2");
Test test = new Test() {
@SuppressWarnings("unused")
public void method() {
System.out.println("\n执行【重写】的method方法");
}
};
//打印返回的引用
System.out.println("\n(匿名内部类)返回的对象:"+test);
//调用匿名内部类对象的成员方法
test.method();
//打印匿名内部类对象的成员变量
System.out.println("\n(Test类)的私有属性:"+test.name);
System.out.println("\n(Test类)的公共属性:"+test.hello);
//调用【非Test类】中的【Test匿名内部类】对象的tempFunction方法
TempTest temp = new TempTest();
temp.tempFunction();
}
//=============================================测试方法3
public void testFunction3() {
System.out.println("\n\n==========================测试方法3");
Callback1 callback1 = new Callback1() {
public void callbackFunction() {
System.out.println("\n执行【重写】后的callbackFunction方法");
}
};
//调用匿名内部类对象的callbackFunction方法
callback1.callbackFunction();
}
//=============================================测试方法4
public void testFunction4(Test test) {
System.out.println("\n\n==========================测试方法4");
System.out.println("\n(匿名内部类)返回的对象:"+test);
test.method();
}
//=============================================测试方法5
public void testFunction5(Callback1 callback) {
System.out.println("\n\n==========================测试方法5");
System.out.println("(匿名内部类)返回的对象:"+callback);
callback.callbackFunction();
}
//=============================================测试方法6
public String testFunction6(Callback2 callback) {
System.out.println("\n\n==========================测试方法6");
System.out.println("\n(匿名内部类)返回的对象:"+callback);
//注:该方法无法访问到匿名内部类中的成员,如callback.name、callback.hello、callback.myFunction
//只能访问接口中的抽象方法
return callback.callbackFunction();
}
//=============================================main方法
public static void main(String[] args) {
Test test = new Test();
//测试1
test.testFunction1();
//测试2
test.testFunction2();
//测试3
test.testFunction3();
//测试4
test.testFunction4(new Test() {
@SuppressWarnings("unused")
public void method () {
System.out.println(this.hello);
System.out.println("\n(匿名类)");
}
});
//测试5
test.testFunction5(new Callback1() {
public void callbackFunction() {
//Callback1类中的私有属性无法被访问,如this.name
System.out.println("\n在(匿名内部类)中访问(Callback1抽象类)中的公共属性:"+this.hello);
System.out.println("\n执行【重写】callback1的callbackFunction方法");
}
});
//测试6
String str = test.testFunction6(new Callback2() {
private String name = "name";
public String hello = "hello";
public String callbackFunction() {
System.out.println("\n只能在(匿名内部类)中访问(匿名内部类)中的属性:"+this.name+"、"+this.hello+"、"+this.myFunction());
return "执行【重写】callback2的callbackFunction方法";
}
public String myFunction() {
return "myFunction";
}
});
System.out.println("\n"+str);
}
}
//用于方便测试的临时类
class TempTest {
//测试2的附属测试方法
public void tempFunction() {
Test test = new Test() {};
System.out.println("\n(匿名内部类)返回的对象:"+test);
//只能调用公共属性
System.out.println("\nTest类的公共属性:"+test.hello);
}
}
abstract class Callback1 {
@SuppressWarnings("unused")
private String name = "name";
public String hello = "hello";
public abstract void callbackFunction();
}
interface Callback2 {
public abstract String callbackFunction();
}
//-----------------------------------------------------------大家最喜欢看结论了-----------------------------------------------------------
//=============================================结论
/*
* 测试1:
*
* 可以new一个匿名内部类,但是里面的方法(如,method方法)是不能直接被执行的。
*/
/*
* 测试2:
*
* 在Test类中的成员方法可以访问Test类中的所有成员,但是{ 无法访问 }在匿名内部类中{ 重写 }的【非抽象】成员方法。
*
* 在Test类外的成员方法不能访问Test类中的私有成员方法。
*/
/*
* 测试3
*
* { 可以访问 }在匿名内部类中{ 重写 }的【抽象】成员方法。
*/
/*
* 测试4
*
* 使用回调函数,结论同测试2。
*/
/*
* 测试5
*
* 使用回调函数,匿名内部类中的方法不能访问所属类的私有成员,结论同测试3。
*/
/*
* 测试6
*
* 使用回调函数,在匿名内部类中的成员只能在匿名内部类内部访问(无论public还是private)除开重写的抽象方法。
*/