package com.fasterxml.jackson.databind;

import java.lang.reflect.Modifier;
import java.util.List;

import com.fasterxml.jackson.core.type.ResolvedType;
import com.fasterxml.jackson.databind.type.TypeBindings;
import com.fasterxml.jackson.databind.type.TypeFactory;

Base class for type token classes used both to contain information and as keys for deserializers.

Instances can (only) be constructed by com.fasterxml.jackson.databind.type.TypeFactory.

Since 2.2 this implements Type to allow it to be pushed through interfaces that only expose that type.

/** * Base class for type token classes used both to contain information * and as keys for deserializers. *<p> * Instances can (only) be constructed by * <code>com.fasterxml.jackson.databind.type.TypeFactory</code>. *<p> * Since 2.2 this implements {@link java.lang.reflect.Type} to allow * it to be pushed through interfaces that only expose that type. */
public abstract class JavaType extends ResolvedType implements java.io.Serializable, // 2.1 java.lang.reflect.Type // 2.2 { private static final long serialVersionUID = 1;
This is the nominal type-erased Class that would be close to the type represented (but not exactly type, due to type erasure: type instance may have more information on this). May be an interface or abstract class, so instantiation may not be possible.
/** * This is the nominal type-erased Class that would be close to the * type represented (but not exactly type, due to type erasure: type * instance may have more information on this). * May be an interface or abstract class, so instantiation * may not be possible. */
protected final Class<?> _class; protected final int _hash;
Optional handler (codec) that can be attached to indicate what to use for handling (serializing, deserializing) values of this specific type.

Note: untyped (i.e. caller has to cast) because it is used for different kinds of handlers, with unrelated types.

/** * Optional handler (codec) that can be attached to indicate * what to use for handling (serializing, deserializing) values of * this specific type. *<p> * Note: untyped (i.e. caller has to cast) because it is used for * different kinds of handlers, with unrelated types. */
protected final Object _valueHandler;
Optional handler that can be attached to indicate how to handle additional type metadata associated with this type.

Note: untyped (i.e. caller has to cast) because it is used for different kinds of handlers, with unrelated types.

/** * Optional handler that can be attached to indicate how to handle * additional type metadata associated with this type. *<p> * Note: untyped (i.e. caller has to cast) because it is used for * different kinds of handlers, with unrelated types. */
protected final Object _typeHandler;
Whether entities defined with this type should be handled using static typing (as opposed to dynamic runtime type) or not.
Since:2.2
/** * Whether entities defined with this type should be handled using * static typing (as opposed to dynamic runtime type) or not. * * @since 2.2 */
protected final boolean _asStatic; /* /********************************************************** /* Life-cycle /********************************************************** */
Params:
  • raw – "Raw" (type-erased) class for this type
  • additionalHash – Additional hash code to use, in addition to hash code of the class name
/** * @param raw "Raw" (type-erased) class for this type * @param additionalHash Additional hash code to use, in addition * to hash code of the class name */
protected JavaType(Class<?> raw, int additionalHash, Object valueHandler, Object typeHandler, boolean asStatic) { _class = raw; _hash = raw.getName().hashCode() + additionalHash; _valueHandler = valueHandler; _typeHandler = typeHandler; _asStatic = asStatic; }
Copy-constructor used when refining/upgrading type instances.
Since:2.7
/** * Copy-constructor used when refining/upgrading type instances. * * @since 2.7 */
protected JavaType(JavaType base) { _class = base._class; _hash = base._hash; _valueHandler = base._valueHandler; _typeHandler = base._typeHandler; _asStatic = base._asStatic; }
"Copy method" that will construct a new instance that is identical to this instance, except that it will have specified type handler assigned.
Returns:Newly created type instance
/** * "Copy method" that will construct a new instance that is identical to * this instance, except that it will have specified type handler assigned. * * @return Newly created type instance */
public abstract JavaType withTypeHandler(Object h);
Mutant factory method that will construct a new instance that is identical to this instance, except that it will have specified content type (element type for arrays, value type for Maps and so forth) handler assigned.
Returns:Newly created type instance, with given
/** * Mutant factory method that will construct a new instance that is identical to * this instance, except that it will have specified content type (element type * for arrays, value type for Maps and so forth) handler assigned. * * @return Newly created type instance, with given */
public abstract JavaType withContentTypeHandler(Object h);
Mutant factory method that will construct a new instance that is identical to this instance, except that it will have specified value handler assigned.
Returns:Newly created type instance
/** * Mutant factory method that will construct a new instance that is identical to * this instance, except that it will have specified value handler assigned. * * @return Newly created type instance */
public abstract JavaType withValueHandler(Object h);
Mutant factory method that will construct a new instance that is identical to this instance, except that it will have specified content value handler assigned.
Returns:Newly created type instance
/** * Mutant factory method that will construct a new instance that is identical to * this instance, except that it will have specified content value handler assigned. * * @return Newly created type instance */
public abstract JavaType withContentValueHandler(Object h);
Mutant factory method that will try to copy handlers that the specified source type instance had, if any; this must be done recursively where necessary (as content types may be structured).
Since:2.8.4
/** * Mutant factory method that will try to copy handlers that the specified * source type instance had, if any; this must be done recursively where * necessary (as content types may be structured). * * @since 2.8.4 */
public JavaType withHandlersFrom(JavaType src) { JavaType type = this; Object h = src.getTypeHandler(); if (h != _typeHandler) { type = type.withTypeHandler(h); } h = src.getValueHandler(); if (h != _valueHandler) { type = type.withValueHandler(h); } return type; }
Mutant factory method that may be called on structured types that have a so-called content type (element of arrays, value type of Maps, referenced type of referential types), and will construct a new instance that is identical to this instance, except that it has specified content type, instead of current one. If content type is already set to given type, this is returned. If type does not have a content type (which is the case with SimpleType), IllegalArgumentException will be thrown.
Returns:Newly created type instance
Since:2.7
/** * Mutant factory method that may be called on structured types * that have a so-called content type (element of arrays, value type * of Maps, referenced type of referential types), * and will construct a new instance that is identical to * this instance, except that it has specified content type, instead of current * one. If content type is already set to given type, <code>this</code> is returned. * If type does not have a content type (which is the case with * <code>SimpleType</code>), {@link IllegalArgumentException} * will be thrown. * * @return Newly created type instance * * @since 2.7 */
public abstract JavaType withContentType(JavaType contentType);
Method that can be called to get a type instance that indicates that values of the type should be handled using "static typing" for purposes of serialization (as opposed to "dynamic" aka runtime typing): meaning that no runtime information is needed for determining serializers to use. The main use case is to allow forcing of specific root value serialization type, and specifically in resolving serializers for contained types (element types for arrays, Collections and Maps).
Since:2.2
/** * Method that can be called to get a type instance that indicates * that values of the type should be handled using "static typing" for purposes * of serialization (as opposed to "dynamic" aka runtime typing): * meaning that no runtime information is needed for determining serializers to use. * The main use case is to allow forcing of specific root value serialization type, * and specifically in resolving serializers for contained types (element types * for arrays, Collections and Maps). * * @since 2.2 */
public abstract JavaType withStaticTyping(); /* /********************************************************** /* Type coercion fluent factory methods /********************************************************** */
Mutant factory method that will try to create and return a sub-type instance for known parameterized types; for other types will return `null` to indicate that no just refinement makes necessary sense, without trying to detect special status through implemented interfaces.
Since:2.7
/** * Mutant factory method that will try to create and return a sub-type instance * for known parameterized types; for other types will return `null` to indicate * that no just refinement makes necessary sense, without trying to detect * special status through implemented interfaces. * * @since 2.7 */
public abstract JavaType refine(Class<?> rawType, TypeBindings bindings, JavaType superClass, JavaType[] superInterfaces);
Legacy method used for forcing sub-typing of this type into type specified by specific type erasure. Deprecated as of 2.7 as such specializations really ought to go through TypeFactory, not directly via JavaType.
Since:2.7
/** * Legacy method used for forcing sub-typing of this type into * type specified by specific type erasure. * Deprecated as of 2.7 as such specializations really ought to * go through {@link TypeFactory}, not directly via {@link JavaType}. * * @since 2.7 */
@Deprecated public JavaType forcedNarrowBy(Class<?> subclass) { if (subclass == _class) { // can still optimize for simple case return this; } return _narrow(subclass); } @Deprecated // since 2.7 protected abstract JavaType _narrow(Class<?> subclass); /* /********************************************************** /* Implementation of ResolvedType API /********************************************************** */ @Override public final Class<?> getRawClass() { return _class; }
Method that can be used to check whether this type has specified Class as its type erasure. Put another way, returns true if instantiation of this Type is given (type-erased) Class.
/** * Method that can be used to check whether this type has * specified Class as its type erasure. Put another way, returns * true if instantiation of this Type is given (type-erased) Class. */
@Override public final boolean hasRawClass(Class<?> clz) { return _class == clz; }
Accessor that allows determining whether getContentType() should return a non-null value (that is, there is a "content type") or not. True if isContainerType() or ResolvedType.isReferenceType() return true.
Since:2.8
/** * Accessor that allows determining whether {@link #getContentType()} should * return a non-null value (that is, there is a "content type") or not. * True if {@link #isContainerType()} or {@link #isReferenceType()} return true. * * @since 2.8 */
public boolean hasContentType() { return true; }
Since:2.6
/** * @since 2.6 */
public final boolean isTypeOrSubTypeOf(Class<?> clz) { return (_class == clz) || clz.isAssignableFrom(_class); }
Since:2.9
/** * @since 2.9 */
public final boolean isTypeOrSuperTypeOf(Class<?> clz) { return (_class == clz) || _class.isAssignableFrom(clz); } @Override public boolean isAbstract() { return Modifier.isAbstract(_class.getModifiers()); }
Convenience method for checking whether underlying Java type is a concrete class or not: abstract classes and interfaces are not.
/** * Convenience method for checking whether underlying Java type * is a concrete class or not: abstract classes and interfaces * are not. */
@Override public boolean isConcrete() { int mod = _class.getModifiers(); if ((mod & (Modifier.INTERFACE | Modifier.ABSTRACT)) == 0) { return true; } /* 19-Feb-2010, tatus: Holy mackarel; primitive types * have 'abstract' flag set... */ return _class.isPrimitive(); } @Override public boolean isThrowable() { return Throwable.class.isAssignableFrom(_class); } @Override public boolean isArrayType() { return false; } @Override public final boolean isEnumType() { return _class.isEnum(); } @Override public final boolean isInterface() { return _class.isInterface(); } @Override public final boolean isPrimitive() { return _class.isPrimitive(); } @Override public final boolean isFinal() { return Modifier.isFinal(_class.getModifiers()); }
Returns:True if type represented is a container type; this includes array, Map and Collection types.
/** * @return True if type represented is a container type; this includes * array, Map and Collection types. */
@Override public abstract boolean isContainerType();
Returns:True if type is either true Collection type, or something similar (meaning it has at least one type parameter, which describes type of contents)
/** * @return True if type is either true {@link java.util.Collection} type, * or something similar (meaning it has at least one type parameter, * which describes type of contents) */
@Override public boolean isCollectionLikeType() { return false; }
Returns:True if type is either true Map type, or something similar (meaning it has at least two type parameter; first one describing key type, second value type)
/** * @return True if type is either true {@link java.util.Map} type, * or something similar (meaning it has at least two type parameter; * first one describing key type, second value type) */
@Override public boolean isMapLikeType() { return false; }
Convenience method, short-hand for getRawClass() == Object.class and used to figure if we basically have "untyped" type object.
Since:2.5
/** * Convenience method, short-hand for *<code> * getRawClass() == Object.class *</code> * and used to figure if we basically have "untyped" type object. * * @since 2.5 */
public final boolean isJavaLangObject() { return _class == Object.class; }
Accessor for checking whether handlers for dealing with values of this type should use static typing (as opposed to dynamic typing). Note that while value of 'true' does mean that static typing is to be used, value of 'false' may still be overridden by other settings.
Since:2.2
/** * Accessor for checking whether handlers for dealing with values of * this type should use static typing (as opposed to dynamic typing). * Note that while value of 'true' does mean that static typing is to * be used, value of 'false' may still be overridden by other settings. * * @since 2.2 */
public final boolean useStaticType() { return _asStatic; } /* /********************************************************** /* Public API, type parameter access; pass-through /********************************************************** */ @Override public boolean hasGenericTypes() { return containedTypeCount() > 0; } @Override public JavaType getKeyType() { return null; } @Override public JavaType getContentType() { return null; } @Override // since 2.6 public JavaType getReferencedType() { return null; } @Override public abstract int containedTypeCount(); @Override public abstract JavaType containedType(int index); @Deprecated // since 2.7 @Override public abstract String containedTypeName(int index); @Deprecated // since 2.7 @Override public Class<?> getParameterSource() { return null; } /* /********************************************************** /* Extended API beyond ResolvedType /********************************************************** */ // NOTE: not defined in Resolved type
Convenience method that is functionally same as: JavaType t = containedType(index); if (t == null) { t = TypeFactory.unknownType(); } and typically used to eliminate need for null checks for common case where we just want to check if containedType is available first; and if not, use "unknown type" (which translates to java.lang.Object basically).
Since:2.5
/** * Convenience method that is functionally same as: *<code> * JavaType t = containedType(index); * if (t == null) { * t = TypeFactory.unknownType(); * } *</code> * and typically used to eliminate need for null checks for common case * where we just want to check if containedType is available first; and * if not, use "unknown type" (which translates to <code>java.lang.Object</code> * basically). * * @since 2.5 */
public JavaType containedTypeOrUnknown(int index) { JavaType t = containedType(index); return (t == null) ? TypeFactory.unknownType() : t; }
Since:2.7
/** * @since 2.7 */
public abstract TypeBindings getBindings();
Method that may be called to find representation of given type within type hierarchy of this type: either this type (if this type has given erased type), one of its supertypes that has the erased types, or null if target is neither this type or any of its supertypes.
Since:2.7
/** * Method that may be called to find representation of given type * within type hierarchy of this type: either this type (if this * type has given erased type), one of its supertypes that has the * erased types, or null if target is neither this type or any of its * supertypes. * * @since 2.7 */
public abstract JavaType findSuperType(Class<?> erasedTarget);
Accessor for finding fully resolved parent class of this type, if it has one; null if not.
Since:2.7
/** * Accessor for finding fully resolved parent class of this type, * if it has one; null if not. * * @since 2.7 */
public abstract JavaType getSuperClass();
Accessor for finding fully resolved interfaces this type implements, if any; empty array if none.
Since:2.7
/** * Accessor for finding fully resolved interfaces this type implements, * if any; empty array if none. * * @since 2.7 */
public abstract List<JavaType> getInterfaces();
Method that may be used to find paramaterization this type has for given type-erased generic target type.
Since:2.7
/** * Method that may be used to find paramaterization this type has for * given type-erased generic target type. * * @since 2.7 */
public abstract JavaType[] findTypeParameters(Class<?> expType); /* /********************************************************** /* Semi-public API, accessing handlers /********************************************************** */
Method for accessing value handler associated with this type, if any
/** * Method for accessing value handler associated with this type, if any */
@SuppressWarnings("unchecked") public <T> T getValueHandler() { return (T) _valueHandler; }
Method for accessing type handler associated with this type, if any
/** * Method for accessing type handler associated with this type, if any */
@SuppressWarnings("unchecked") public <T> T getTypeHandler() { return (T) _typeHandler; }
Since:2.7
/** * @since 2.7 */
public Object getContentValueHandler() { return null; }
Since:2.7
/** * @since 2.7 */
public Object getContentTypeHandler() { return null; }
Since:2.6
/** * @since 2.6 */
public boolean hasValueHandler() { return _valueHandler != null; }
Helper method that checks whether this type, or its (optional) key or content type has getValueHandler or getTypeHandler(); that is, are there any non-standard handlers associated with this type object.
Since:2.8
/** * Helper method that checks whether this type, or its (optional) key * or content type has {@link #getValueHandler} or {@link #getTypeHandler()}; * that is, are there any non-standard handlers associated with this * type object. * * @since 2.8 */
public boolean hasHandlers() { return (_typeHandler != null) || (_valueHandler != null); } /* /********************************************************** /* Support for producing signatures /********************************************************** */ //public abstract String toCanonical();
Method for accessing signature that contains generic type information, in form compatible with JVM 1.5 as per JLS. It is a superset of getErasedSignature, in that generic information can be automatically removed if necessary (just remove outermost angle brackets along with content inside)
/** * Method for accessing signature that contains generic * type information, in form compatible with JVM 1.5 * as per JLS. It is a superset of {@link #getErasedSignature}, * in that generic information can be automatically removed * if necessary (just remove outermost * angle brackets along with content inside) */
public String getGenericSignature() { StringBuilder sb = new StringBuilder(40); getGenericSignature(sb); return sb.toString(); }
Params:
  • sb – StringBuilder to append signature to
Returns:StringBuilder that was passed in; returned to allow call chaining
/** * * @param sb StringBuilder to append signature to * * @return StringBuilder that was passed in; returned to allow * call chaining */
public abstract StringBuilder getGenericSignature(StringBuilder sb);
Method for accessing signature without generic type information, in form compatible with all versions of JVM, and specifically used for type descriptions when generating byte code.
/** * Method for accessing signature without generic * type information, in form compatible with all versions * of JVM, and specifically used for type descriptions * when generating byte code. */
public String getErasedSignature() { StringBuilder sb = new StringBuilder(40); getErasedSignature(sb); return sb.toString(); }
Method for accessing signature without generic type information, in form compatible with all versions of JVM, and specifically used for type descriptions when generating byte code.
Params:
  • sb – StringBuilder to append signature to
Returns:StringBuilder that was passed in; returned to allow call chaining
/** * Method for accessing signature without generic * type information, in form compatible with all versions * of JVM, and specifically used for type descriptions * when generating byte code. * * @param sb StringBuilder to append signature to * * @return StringBuilder that was passed in; returned to allow * call chaining */
public abstract StringBuilder getErasedSignature(StringBuilder sb); /* /********************************************************** /* Standard methods; let's make them abstract to force override /********************************************************** */ @Override public abstract String toString(); @Override public abstract boolean equals(Object o); @Override public final int hashCode() { return _hash; } }