我知道,当一个类具有内部类时,该类将被编译为两个类文件。今天我有如下代码

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>>
{
}


有人可以解释为什么创建此类吗?
以及何时在编译时创建多个类文件?

非常感谢!

最佳答案

new TypeToken<GenericResult<City>>() {
}


创建一个匿名内部类。就像内部类一样,匿名内部类也被编译为单独的类文件。由于匿名类没有名称,这就是为什么使用数字为每个此类生成唯一名称的原因。您在$之后看到的数字是该匿名类的编号,因为它们在您的封闭类中按顺序排列。

如果您使用更多类似的匿名类,则数字将增加1。因此,对于更多匿名类,生成的类文件将类似于:

GenericDeserializer$1.class
GenericDeserializer$2.class
GenericDeserializer$3.class
GenericDeserializer$4.class
....


但是,对于内部类,如您已经注意到的,$之后的值是内部类的名称。


  以及何时在编译时创建多个类文件?


是的,当您编译顶级类时,将生成这些类。

10-06 14:33