我知道当一个类有一个内部类时,这个类将被编译为两个类文件。今天我的代码如下
public class GenericDeserializer {
public static void main(String[] args) {
String cityPageLoadJson = "{\"count\":2,\"pageLoad\":[{\"id\":4,\"name\":\"HAN\"},{\"id\":8,\"name\":\"SGN\"}]}";
Type type = new TypeToken<GenericResult<City>>() {
}.getType();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
GenericResult<City> cityPageLoad = gson.fromJson(cityPageLoadJson, type);
for (City city : cityPageLoad.getPageLoad()) {
System.out.println(gson.toJson(city));
}
}
}
虽然上面没有内部类,但java编译器仍会创建两个类文件:
GenericDeserializer.class
GenericDeserializer$1.class
使用Java Decompiler
工具,我会看到第二个
package net.tuandn.training.lesson.gson;
import com.google.gson.reflect.TypeToken;
import net.tuandn.training.model.City;
import net.tuandn.training.model.GenericResult;
final class GenericDeserializer$1 extends TypeToken<GenericResult<City>>
{
}
有人可以解释为什么要创建这个课程吗? 什么时候在编译时创建多个类文件?
非常感谢!
答案 0 :(得分:5)
生成两个类文件,因为您在以下语句中使用了anonymous
类:
TypeToken<GenericResult<City>>() {
.....
}
每个匿名类文件使用与容器类相同的名称,并附加$ 1 / $ 2,依此类推。
答案 1 :(得分:4)
new TypeToken<GenericResult<City>>() {
}
创建一个匿名内部类。匿名内部类,就像内部类一样,被编译为单独的类文件。由于匿名类没有名称,因此 numbers 用于为每个此类生成唯一名称。您在$
之后看到的数字是该匿名类的编号,因为它们在您的封闭类中按顺序排列。
如果您使用更多类似的匿名类,则数字将增加1
。因此,对于更多匿名类,生成的类文件将如下所示:
GenericDeserializer$1.class
GenericDeserializer$2.class
GenericDeserializer$3.class
GenericDeserializer$4.class
....
但是对于内部类,$
之后的值是内部类的名称,正如您已经注意到的那样。
何时在编译时创建多个类文件?
是的,在编译顶级类时会生成这些类。
答案 2 :(得分:2)
很简单,您的反编译类显示
final class GenericDeserializer$1 extends TypeToken<GenericResult<City>>
所以你在某个地方TypeToken<GenericResult<City>>
。
查看您的代码,我们看到了
Type type = new TypeToken<GenericResult<City>>() { /* anonymous inner class */ }.getType();
那里有一个匿名的内部类声明,因此将获得带有$X
后缀的自己的类文件。