Skip to content
Advertisement

Why protected constructor can be used to new instance outside of the package?

From gson-2.8.6.jar

package com.google.gson.reflect;
...
public class TypeToken<T> {
  final Class<? super T> rawType;
  final Type type;
  final int hashCode;

  /**
   * Constructs a new type literal. Derives represented class from type
   * parameter.
   *
   * <p>Clients create an empty anonymous subclass. Doing so embeds the type
   * parameter in the anonymous class's type hierarchy so we can reconstitute it
   * at runtime despite erasure.
   */
  @SuppressWarnings("unchecked")
  protected TypeToken() {
    this.type = getSuperclassTypeParameter(getClass());
    this.rawType = (Class<? super T>) $Gson$Types.getRawType(type);
    this.hashCode = type.hashCode();
  }

  /**
   * Unsafe. Constructs a type literal manually.
   */
  @SuppressWarnings("unchecked")
  TypeToken(Type type) {
    this.type = $Gson$Types.canonicalize($Gson$Preconditions.checkNotNull(type));
    this.rawType = (Class<? super T>) $Gson$Types.getRawType(this.type);
    this.hashCode = this.type.hashCode();
  }
...
}

Outside of the package com.google.gson.reflect, why the protected TypeToken() constructor can be used to new an instance?
What’s the grammar that {} appear after new TypeToken<String>()?

package com.dataservice.controller;

...
Type localVarReturnType = (new TypeToken<String>() {}).getType();
...

Advertisement

Answer

What you are seeing is the syntax for an anonymous class:

Essentially what happens is,

Type localVarReturnType = (new TypeToken<String>() {}).getType();

defines a new anonymous class which inherits from TypeToken. You can immediately derive this from the syntax new in combination with curly braces {}.

The reason why you are allowed to access the protected constructor, is because protected allows access for the package OR for inheriting classes. Since your anonymous class inherits from TypeToken access is then possible.

Advertisement