1. 程式人生 > >new關鍵字創建對象帶不帶{}的區別

new關鍵字創建對象帶不帶{}的區別

pac user bject 2個 測試類 simple 而是 creat str

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一致。

new關鍵字創建對象帶不帶{}的區別