0

我是 Java 编程新手。在阅读一个开源项目的代码时,我遇到了一行我无法理解的代码:

final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();

我的问题是:

  1. 我通常这样调用构造函数:final Type typeOfMap = new TypeToken<Map<String, Object>>(). 我从未见过它后面跟着其他代码,例如{}.getType(). 这是什么语法?
  2. {}对象吗?为什么可以在上面调用一个函数?

PSTypejava.lang.reflect.Type,而且TypeTokencom.google.gson.reflect.TypeToken

4

2 回答 2

0

我也是 Java 的新手,但据我所知,这是一个属于抽象泛型类new TypeToken<Map<String, Object>>() {}的构造函数 类 tiself 可能看起来像这样:public abstract class TypeToken<X>......现在,对于.getType().我不太确定的方法这是如何编码的。你提醒我这是我要学习/理解的东西的清单,但我很确定这个代码模式有点过度设计,(这可能是我的偏见,正是因为我不知道它或它是什么可能有用)

.getType()方法,可以是抽象内部的一个公开的非抽象的方法。

我个人发现在某些情况下(只是在某些情况下),实例化抽象对象而不是扩展它们(这是它们通常的使用方式)更方便,特别是在您的抽象对象需要在特定位置创建另一个对象的情况下生命周期,或者当抽象对象需要在同一个类中进行互操作时。

现在,如果我没记错的话,我认为特定的实现com.google.gson.reflect.TypeToken使用反射来获取非初始化对象的类类型,而无需实际创建对象(也许它在幕后),如果你试图为嵌套的泛型类创建一个新实例,你知道它是如何令人头疼的,因为所谓的“擦除”。

于 2020-09-04T03:09:48.263 回答
0

我通常这样调用构造函数:final Type typeOfMap = new TypeToken<Map<String, Object>>()。我从未见过它后面跟着其他代码,例如 {}.getType()。这是什么语法?

它是匿名内部类的语法。

{} 是一个对象吗?为什么可以在上面调用一个函数?

是的,你从中得到一个对象。这就是为什么可以在其上调用方法的原因。

当您需要一个类的特定行为一次时,匿名类很有用。就像下面的例子一样,如果你在普通的 A 对象上调用 sayHello,那么它将返回 Hello。但是,对于匿名类的对象,sayHello 方法的行为发生了变化,这次它返回 Bonjour。

public class SomeClass {

    public static void main(String[] args) {

        A defaultObj = new A();
        A customObj = new A() {
            @Override
            public String sayHello() {
                return "Bonjour";
            }
        };

        System.out.println(defaultObj.sayHello());
        System.out.println(customObj.sayHello());

    }
}

class A {
    String sayHello() {
        return "Hello";
    }
}

输出

Hello
Bonjour

TypeToken 的 Gson 文档也提到了匿名类的原因和用法。在 TypeToken 类中使用的原因是它用于在运行时检索令牌的类型。否则,由于类型擦除,泛型类型信息在运行时不可用。

https://www.javadoc.io/doc/com.google.code.gson/gson/2.6.2/com/google/gson/reflect/TypeToken.html

表示泛型类型 T。Java 还没有提供表示泛型类型的方法,所以这个类提供了。强制客户端创建此类的子类,即使在运行时也可以检索类型信息。例如,要为 List 创建类型文字,您可以创建一个空的匿名内部类:

TypeToken<List> list = new TypeToken<List>() {};

于 2020-09-04T02:44:57.370 回答