如何new一个在不同个包中且只有protected构造方法的类的对象呢?在讲解如何实现之前,来讲一下事情的缘由。下面将说明如何实现(这里主要讲的是如何使用匿名内部类实现)。后续描述的内容如有问题请广大读者能够耐心指出,给读者带来不便之处,还请见谅。
在使用gson解析json字符串的时候,使用到如下代码:
Gson gson = new Gson();
List orderDetailList = new ArrayList<>();
orderDetailList = gson.fromJson(orderForm.getItems(), new TypeToken<List>() {}.getType());
其中最引人注目的当属,这部分代码:
new TypeToken<List>() {}.getType()
这里使用了匿名内部类(且内部未做任何操作),查看TypeToken
类源码会发现,该类中只存在一个使用protected
修饰的无参构造方法,在正常情况下,我们使用在不同的包中new
出这样的对象(当然我指的是new
的使用调用的构造方法是使用protected
修饰的。),那么这里已经教我们如何处理了,即采用匿名内部类。
为更好的描述一个实现过程,我们先来创建一个类,SupperClass,且位于com.wm103.test
包中,如下:
package com.wm103.test;
public class SupperClass {
private String message;
protected SupperClass() {
System.out.println("supper class init.");
}
public void print() {
System.out.println("This is supper class.");
System.out.println("message: " + this.getMessage());
}
public String getMessage() {
return this.message;
}
public void setMessage(String message) {
this.message = message;
}
}
我们再来创建一个主类,MainClass,且位于com.wm103
包中,如下:
package com.wm103;
import com.wm103.test.SupperClass;
public class MainClass {
public static void main(String[] args) {
new SupperClass();
}
}
直接new SupperClass()
,我想你会在IDE中看到类似这样的提示:
'SupperClass()' has protected access in 'com.wm103.test.SupperClass'
因为SupperClass()
构造方法是protected
访问权限,而MainClass
与SupperClass
不在同个包中,所以并不能直接new SupperClass()
。那么我们该怎么做呢?采用匿名内部类。如下:
new SupperClass() {}.print();
在这样的情况下,我们即可创建匿名内部类对象,且调用SupperClass
类的print
方法。
匿名内部类中是不能定义构造函数的。而我们一般都是利用构造器来完成某个实例的初始化工作的,那么在匿名内部类中我们应该如何实现初始化操作呢?使用构造代码块!利用构造代码块能够达到为匿名内部类创建一个构造器的效果。
还是以上述中的例子为例,如下:
new SupperClass() {
{
setMessage("Hello Supper Class.");
innerPrint();
}
public void innerPrint() {
System.out.println("This is inner class.");
}
}.print();
在上述的匿名内部中,定义了构造代码块用来实现初始化操作,还定义了一个属于自己的方法。运行这样的例子,将在控制台看到这样的输出结果:
supper class init.
This is inner class.
This is supper class.
message: Hello Supper Class.
具体流程如下:调用SupperClass的构造方法进行初始化 -> 运行匿名内部类的构造代码块 -> 调用print方法(方法内输出了在构造代码块初始化的message的值)。
如果在匿名内部中定义与SupperClass中同名的方法,又会将如何呢(会发生方法覆盖),如下:
new SupperClass() {
{
setMessage("Hello Supper Class.");
innerPrint();
}
public void innerPrint() {
System.out.println("This is inner class.");
}
public void print() {
System.out.println("inner class::print");
}
}.print();
运行结果如下:
supper class init.
This is inner class.
inner class::print