/*
* Copyright 2014 - 2020 Rafael Winterhalter
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.bytebuddy.description.type;
import net.bytebuddy.description.ModifierReviewable;
import net.bytebuddy.description.NamedElement;
import net.bytebuddy.description.field.FieldList;
import net.bytebuddy.description.method.MethodList;
import net.bytebuddy.implementation.bytecode.StackSize;
import java.lang.reflect.*;
import java.util.Iterator;
import java.util.NoSuchElementException;
Implementations define a type, either as a TypeDescription
or as a Generic
. /**
* Implementations define a type, either as a {@link TypeDescription} or as a {@link TypeDescription.Generic}.
*/
public interface TypeDefinition extends NamedElement, ModifierReviewable.ForTypeDefinition, Iterable<TypeDefinition> {
If this property is set to true
, non-generic TypeDefinition
s do no longer resolve their referenced generic types when traversing type hierarchies. Setting this property can cause unexpected side effects such as ClassCastException
s from overridden methods as type variables are resolved to their erasures where a method might return that is unexpected by the callee. Setting this property also makes type annotations unavailable using such type navigation.
Setting this property can be useful if generic type information is not required in order to avoid bugs in
implementations of the JVM where processing generic types can cause segmentation faults. Byte Buddy will undertake
a best effort to retain the generic type information and information about type annotations within the redefined
types' class files. Typically, this property can be meaningful in combination with a Java agent that only changes
byte code without changing a class type's structure.
/**
* <p>
* If this property is set to {@code true}, non-generic {@link TypeDefinition}s do no longer resolve their referenced
* generic types when traversing type hierarchies. Setting this property can cause unexpected side effects such as
* {@link ClassCastException}s from overridden methods as type variables are resolved to their erasures where a method
* might return that is unexpected by the callee. Setting this property also makes type annotations unavailable using
* such type navigation.
* </p>
* <p>
* Setting this property can be useful if generic type information is not required in order to avoid bugs in
* implementations of the JVM where processing generic types can cause segmentation faults. Byte Buddy will undertake
* a best effort to retain the generic type information and information about type annotations within the redefined
* types' class files. Typically, this property can be meaningful in combination with a Java agent that only changes
* byte code without changing a class type's structure.
* </p>
*/
String RAW_TYPES_PROPERTY = "net.bytebuddy.raw";
Returns this type definition as a generic type.
Returns: This type definition represented as a generic type.
/**
* Returns this type definition as a generic type.
*
* @return This type definition represented as a generic type.
*/
TypeDescription.Generic asGenericType();
Returns the erasure of this type. Wildcard types (Sort.WILDCARD
) do not have a well-defined erasure and cause an IllegalStateException
to be thrown. Returns: The erasure of this type.
/**
* Returns the erasure of this type. Wildcard types ({@link TypeDescription.Generic.Sort#WILDCARD})
* do not have a well-defined erasure and cause an {@link IllegalStateException} to be thrown.
*
* @return The erasure of this type.
*/
TypeDescription asErasure();
Returns the super class of this type. A super type is only defined for non-generic types (Sort.NON_GENERIC
), parameterized types (Sort.PARAMETERIZED
) or generic array types (Sort.GENERIC_ARRAY
) types. Interface types and the Object
class do not define a super class where null
is returned. Array types define Object
as their direct super class. Returns: The super class of this type or null
if no super class exists for this type.
/**
* Returns the super class of this type. A super type is only defined for non-generic types ({@link Sort#NON_GENERIC}),
* parameterized types ({@link Sort#PARAMETERIZED}) or generic array types ({@link Sort#GENERIC_ARRAY}) types. Interface types
* and the {@link Object} class do not define a super class where {@code null} is returned. Array types define {@link Object}
* as their direct super class.
*
* @return The super class of this type or {@code null} if no super class exists for this type.
*/
TypeDescription.Generic getSuperClass();
Returns the interfaces that this type implements. A super type is only defined for non-generic types (Sort.NON_GENERIC
), parameterized types (Sort.PARAMETERIZED
) or generic array types (Sort.GENERIC_ARRAY
) types. Returns: The interfaces that this type implements.
/**
* Returns the interfaces that this type implements. A super type is only defined for non-generic types ({@link Sort#NON_GENERIC}),
* parameterized types ({@link Sort#PARAMETERIZED}) or generic array types ({@link Sort#GENERIC_ARRAY}) types.
*
* @return The interfaces that this type implements.
*/
TypeList.Generic getInterfaces();
Returns the fields that this type declares. A super type is only defined for non-generic types (Sort.NON_GENERIC
), parameterized types (Sort.PARAMETERIZED
) or generic array types (Sort.GENERIC_ARRAY
) types. Generic array types never define fields and the returned list is always empty for such types. Returns: The fields that this type declares. A super type is only defined for non-generic types (Sort.NON_GENERIC
), parameterized types (Sort.PARAMETERIZED
) or generic array types (Sort.GENERIC_ARRAY
) types. Generic array types never define methods and the returned list is always empty for such types.
/**
* Returns the fields that this type declares. A super type is only defined for non-generic types ({@link Sort#NON_GENERIC}),
* parameterized types ({@link Sort#PARAMETERIZED}) or generic array types ({@link Sort#GENERIC_ARRAY}) types. Generic array
* types never define fields and the returned list is always empty for such types.
*
* @return The fields that this type declares. A super type is only defined for non-generic types ({@link Sort#NON_GENERIC}),
* parameterized types ({@link Sort#PARAMETERIZED}) or generic array types ({@link Sort#GENERIC_ARRAY}) types. Generic array
* types never define methods and the returned list is always empty for such types.
*/
FieldList<?> getDeclaredFields();
Returns the methods that this type declares.
Returns: The methods that this type declares.
/**
* Returns the methods that this type declares.
*
* @return The methods that this type declares.
*/
MethodList<?> getDeclaredMethods();
Returns the component type of this type.
Only non-generic types (Sort.NON_GENERIC
) and generic array types Sort.GENERIC_ARRAY
) define a component type. For other types, an IllegalStateException
is thrown.
Returns: The component type of this type or null
if this type does not represent an array type.
/**
* <p>
* Returns the component type of this type.
* </p>
* <p>
* Only non-generic types ({@link TypeDescription.Generic.Sort#NON_GENERIC}) and generic array types
* {@link TypeDescription.Generic.Sort#GENERIC_ARRAY}) define a component type. For other
* types, an {@link IllegalStateException} is thrown.
* </p>
*
* @return The component type of this type or {@code null} if this type does not represent an array type.
*/
TypeDefinition getComponentType();
Returns the list of record components that are declared by this type. If this type is not
a record, the returned list is empty.
Returns: A list of record components that this type declares.
/**
* Returns the list of record components that are declared by this type. If this type is not
* a record, the returned list is empty.
*
* @return A list of record components that this type declares.
*/
RecordComponentList<?> getRecordComponents();
Returns the sort of the generic type this instance represents.
Returns: The sort of the generic type.
/**
* Returns the sort of the generic type this instance represents.
*
* @return The sort of the generic type.
*/
Sort getSort();
Returns the name of the type. For generic types, this name is their Object.toString()
representations. For a non-generic type, it is the fully qualified binary name of the type. Returns: The name of this type.
/**
* Returns the name of the type. For generic types, this name is their {@link Object#toString()} representations. For a non-generic
* type, it is the fully qualified binary name of the type.
*
* @return The name of this type.
*/
String getTypeName();
Returns the size of the type described by this instance. Wildcard types (Sort.WILDCARD
do not have a well-defined a stack size and cause an IllegalStateException
to be thrown. Returns: The size of the type described by this instance.
/**
* Returns the size of the type described by this instance. Wildcard types
* ({@link TypeDescription.Generic.Sort#WILDCARD} do not have a well-defined a stack size and
* cause an {@link IllegalStateException} to be thrown.
*
* @return The size of the type described by this instance.
*/
StackSize getStackSize();
Checks if the type described by this entity is an array.
Returns: true
if this type description represents an array.
/**
* Checks if the type described by this entity is an array.
*
* @return {@code true} if this type description represents an array.
*/
boolean isArray();
Checks if this type is a Java record.
Returns: true
if this type is a Java record.
/**
* Checks if this type is a Java record.
*
* @return {@code true} if this type is a Java record.
*/
boolean isRecord();
Checks if the type described by this entity is a primitive type.
Returns: true
if this type description represents a primitive type.
/**
* Checks if the type described by this entity is a primitive type.
*
* @return {@code true} if this type description represents a primitive type.
*/
boolean isPrimitive();
Checks if the type described by this instance represents type
. Params: - type – The type of interest.
Returns: true
if the type described by this instance represents type
.
/**
* Checks if the type described by this instance represents {@code type}.
*
* @param type The type of interest.
* @return {@code true} if the type described by this instance represents {@code type}.
*/
boolean represents(Type type);
Represents a Generic
's form. /**
* Represents a {@link TypeDescription.Generic}'s form.
*/
enum Sort {
Represents a non-generic type.
/**
* Represents a non-generic type.
*/
NON_GENERIC,
Represents a generic array type.
/**
* Represents a generic array type.
*/
GENERIC_ARRAY,
Represents a parameterized type.
/**
* Represents a parameterized type.
*/
PARAMETERIZED,
Represents a wildcard type.
/**
* Represents a wildcard type.
*/
WILDCARD,
Represents a type variable that is attached to a TypeVariableSource
. /**
* Represents a type variable that is attached to a {@link net.bytebuddy.description.TypeVariableSource}.
*/
VARIABLE,
Represents a type variable that is merely symbolic and is not attached to a TypeVariableSource
and does not defined bounds. /**
* Represents a type variable that is merely symbolic and is not attached to a {@link net.bytebuddy.description.TypeVariableSource}
* and does not defined bounds.
*/
VARIABLE_SYMBOLIC;
Describes a loaded generic type as a Generic
. Params: - type – The type to describe.
Returns: A description of the provided generic type.
/**
* Describes a loaded generic type as a {@link TypeDescription.Generic}.
*
* @param type The type to describe.
* @return A description of the provided generic type.
*/
public static TypeDescription.Generic describe(Type type) {
return describe(type, TypeDescription.Generic.AnnotationReader.NoOp.INSTANCE);
}
Describes the generic type while using the supplied annotation reader for resolving type annotations if this
language feature is available on the current JVM.
Params: - type – The type to describe.
- annotationReader – The annotation reader for extracting type annotations.
Returns: A description of the provided generic annotated type.
/**
* Describes the generic type while using the supplied annotation reader for resolving type annotations if this
* language feature is available on the current JVM.
*
* @param type The type to describe.
* @param annotationReader The annotation reader for extracting type annotations.
* @return A description of the provided generic annotated type.
*/
protected static TypeDescription.Generic describe(Type type, TypeDescription.Generic.AnnotationReader annotationReader) {
if (type instanceof Class<?>) {
return new TypeDescription.Generic.OfNonGenericType.ForLoadedType((Class<?>) type, annotationReader);
} else if (type instanceof GenericArrayType) {
return new TypeDescription.Generic.OfGenericArray.ForLoadedType((GenericArrayType) type, annotationReader);
} else if (type instanceof ParameterizedType) {
return new TypeDescription.Generic.OfParameterizedType.ForLoadedType((ParameterizedType) type, annotationReader);
} else if (type instanceof TypeVariable) {
return new TypeDescription.Generic.OfTypeVariable.ForLoadedType((TypeVariable<?>) type, annotationReader);
} else if (type instanceof WildcardType) {
return new TypeDescription.Generic.OfWildcardType.ForLoadedType((WildcardType) type, annotationReader);
} else {
throw new IllegalArgumentException("Unknown type: " + type);
}
}
Checks if this type sort represents a non-generic type.
Returns: true
if this sort form represents a non-generic.
/**
* Checks if this type sort represents a non-generic type.
*
* @return {@code true} if this sort form represents a non-generic.
*/
public boolean isNonGeneric() {
return this == NON_GENERIC;
}
Checks if this type sort represents a parameterized type.
Returns: true
if this sort form represents a parameterized type.
/**
* Checks if this type sort represents a parameterized type.
*
* @return {@code true} if this sort form represents a parameterized type.
*/
public boolean isParameterized() {
return this == PARAMETERIZED;
}
Checks if this type sort represents a generic array.
Returns: true
if this type sort represents a generic array.
/**
* Checks if this type sort represents a generic array.
*
* @return {@code true} if this type sort represents a generic array.
*/
public boolean isGenericArray() {
return this == GENERIC_ARRAY;
}
Checks if this type sort represents a wildcard.
Returns: true
if this type sort represents a wildcard.
/**
* Checks if this type sort represents a wildcard.
*
* @return {@code true} if this type sort represents a wildcard.
*/
public boolean isWildcard() {
return this == WILDCARD;
}
Checks if this type sort represents a type variable of any form.
Returns: true
if this type sort represents an attached type variable.
/**
* Checks if this type sort represents a type variable of any form.
*
* @return {@code true} if this type sort represents an attached type variable.
*/
public boolean isTypeVariable() {
return this == VARIABLE || this == VARIABLE_SYMBOLIC;
}
}
An iterator that iterates over a type's class hierarchy.
/**
* An iterator that iterates over a type's class hierarchy.
*/
class SuperClassIterator implements Iterator<TypeDefinition> {
The next class to represent.
/**
* The next class to represent.
*/
private TypeDefinition nextClass;
Creates a new iterator.
Params: - initialType – The initial type of this iterator.
/**
* Creates a new iterator.
*
* @param initialType The initial type of this iterator.
*/
public SuperClassIterator(TypeDefinition initialType) {
nextClass = initialType;
}
{@inheritDoc}
/**
* {@inheritDoc}
*/
public boolean hasNext() {
return nextClass != null;
}
{@inheritDoc}
/**
* {@inheritDoc}
*/
public TypeDefinition next() {
if (!hasNext()) {
throw new NoSuchElementException("End of type hierarchy");
}
try {
return nextClass;
} finally {
nextClass = nextClass.getSuperClass();
}
}
{@inheritDoc}
/**
* {@inheritDoc}
*/
public void remove() {
throw new UnsupportedOperationException("remove");
}
}
}