new关键字创建对象带不带{}的区别
gson通过TypeToken实现了对泛型数据的支持,使用方式如下:
gson.fromJson([待转化的字符串], new TypeToken<[目标类]<目标类中的泛型>>(){}.getType())
创建一个类实例,new [目标类]()就够了,TypeToken后面的{}是做什么呢,不少人可能像我一样有困惑。
先看下TypeToken的构造方法
protected TypeToken() { this.type = getSuperclassTypeParameter(getClass()); this.rawType = (Class<? super T>) $Gson$Types.getRawType(type); this.hashCode = type.hashCode(); }
static Type getSuperclassTypeParameter(Class<?> subclass) { Type superclass = subclass.getGenericSuperclass(); if (superclass instanceof Class) { throw new RuntimeException("Missing type parameter."); } ParameterizedType parameterized = (ParameterizedType) superclass; return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]); }
这里我们只关注标红的部分。为了方便说明,我们写一个测试类,使用上面的2个方法,并打印出来。
package com.ym.materials.jdk; import org.junit.Test; /** * Created by ym on 2018/6/30. */ public class ConstructorDiff { public static class ClassRoom{ } public static class User<T>{ private T room; public User() { System.out.println(this.getClass()); System.out.println(this.getClass().getGenericSuperclass()); } } @Test public void testSimpleConstructor() throws Exception { new User<ClassRoom>(); } @Test public void testConstructorWithBrace() throws Exception { new User<ClassRoom>(){}; } }
执行结果如下:
class com.ym.materials.jdk.ConstructorDiff$User class java.lang.Object
class com.ym.materials.jdk.ConstructorDiff$1 com.ym.materials.jdk.ConstructorDiff.com.ym.materials.jdk.ConstructorDiff$User<com.ym.materials.jdk.ConstructorDiff$ClassRoom>
testConstructorWithBrace不是User,而是$1,$前缀是jdk隐藏内部类的命名规则,所以答案已经明了了,{}不是直接调用构造去创建实例,而是先创建一个类,再去实例化。等价于定义一个$1的类结构,再去实例化。
public class $1 extends User<ClassRoom> { } @Test public void test$1() throws Exception { new $1(); }
输出结构与testConstructorWithBrace一致。