有src.zip中有的源码有.
AnnotationInvocationHandler 就sun这个包好像就没有.
怎么解决?
sun
开头的类是人家JDK内部的类,就不是给你用的,而且JDK1.8是LTS版,有重大问题还是维护的,小版本还在增加,迭代过程中,获取会修改删除一些内部类
以下代码是net.bytebuddy.description.annotation.AnnotationDescription.AnnotationInvocationHandler
的,来自cglib
如有需要,可以参考
/**
* An {@link java.lang.reflect.InvocationHandler} for implementing annotations.
*
* @param <T> The type of the handled annotation.
*/
class AnnotationInvocationHandler<T extends Annotation> implements InvocationHandler {
/**
* The name of the {@link Object#hashCode()} method.
*/
private static final String HASH_CODE = "hashCode";
/**
* The name of the {@link Object#equals(Object)} method.
*/
private static final String EQUALS = "equals";
/**
* The name of the {@link Object#toString()} method.
*/
private static final String TO_STRING = "toString";
/**
* An empty array that can be used to indicate no arguments to avoid an allocation on a reflective call.
*/
private static final Object[] NO_ARGUMENTS = new Object[0];
/**
* The loaded annotation type.
*/
private final Class<? extends Annotation> annotationType;
/**
* A sorted list of values of this annotation.
*/
private final LinkedHashMap<Method, AnnotationValue.Loaded<?>> values;
/**
* Creates a new invocation handler.
*
* @param annotationType The loaded annotation type.
* @param values A sorted list of values of this annotation.
*/
protected AnnotationInvocationHandler(Class<T> annotationType, LinkedHashMap<Method, AnnotationValue.Loaded<?>> values) {
this.annotationType = annotationType;
this.values = values;
}
/**
* Creates a proxy instance for the supplied annotation type and values.
*
* @param classLoader The class loader that should be used for loading the annotation's values.
* @param annotationType The annotation's type.
* @param values The values that the annotation contains.
* @param <S> The type of the handled annotation.
* @return A proxy for the annotation type and values.
* @throws ClassNotFoundException If the class of an instance that is contained by this annotation could not be found.
*/
@SuppressWarnings("unchecked")
public static <S extends Annotation> S of(ClassLoader classLoader,
Class<S> annotationType,
Map<String, ? extends AnnotationValue<?, ?>> values) throws ClassNotFoundException {
LinkedHashMap<Method, AnnotationValue.Loaded<?>> loadedValues = new LinkedHashMap<Method, AnnotationValue.Loaded<?>>();
for (Method method : annotationType.getDeclaredMethods()) {
AnnotationValue<?, ?> annotationValue = values.get(method.getName());
loadedValues.put(method, (annotationValue == null
? defaultValueOf(method)
: annotationValue).load(classLoader));
}
return (S) Proxy.newProxyInstance(classLoader, new Class<?>[]{annotationType}, new AnnotationInvocationHandler<S>(annotationType, loadedValues));
}
/**
* Creates a default value for the given method.
*
* @param method The method from which to attempt the extraction of a default value.
* @return A default value representation.
*/
private static AnnotationValue<?, ?> defaultValueOf(Method method) {
Object defaultValue = method.getDefaultValue();
return defaultValue == null
? MissingValue.of(method)
: AnnotationDescription.ForLoadedAnnotation.asValue(defaultValue, method.getReturnType());
}
/**
* Resolves any primitive type to its wrapper type.
*
* @param type The type to resolve.
* @return The resolved type.
*/
private static Class<?> asWrapper(Class<?> type) {
if (type.isPrimitive()) {
if (type == boolean.class) {
return Boolean.class;
} else if (type == byte.class) {
return Byte.class;
} else if (type == short.class) {
return Short.class;
} else if (type == char.class) {
return Character.class;
} else if (type == int.class) {
return Integer.class;
} else if (type == long.class) {
return Long.class;
} else if (type == float.class) {
return Float.class;
} else if (type == double.class) {
return Double.class;
}
}
return type;
}
/**
* {@inheritDoc}
*/
public Object invoke(Object proxy, Method method, Object[] argument) {
if (method.getDeclaringClass() != annotationType) {
if (method.getName().equals(HASH_CODE)) {
return hashCodeRepresentation();
} else if (method.getName().equals(EQUALS) && method.getParameterTypes().length == 1) {
return equalsRepresentation(proxy, argument[0]);
} else if (method.getName().equals(TO_STRING)) {
return toStringRepresentation();
} else /* if (method.getName().equals("annotationType")) */ {
return annotationType;
}
}
Object value = values.get(method).resolve();
if (!asWrapper(method.getReturnType()).isAssignableFrom(value.getClass())) {
throw new AnnotationTypeMismatchException(method, value.getClass().toString());
}
return value;
}
/**
* Returns the string representation of the represented annotation.
*
* @return The string representation of the represented annotation.
*/
protected String toStringRepresentation() {
StringBuilder toString = new StringBuilder();
toString.append('@');
toString.append(annotationType.getName());
toString.append('(');
boolean firstMember = true;
for (Map.Entry<Method, AnnotationValue.Loaded<?>> entry : values.entrySet()) {
if (!entry.getValue().getState().isDefined()) {
continue;
}
if (firstMember) {
firstMember = false;
} else {
toString.append(", ");
}
toString.append(entry.getKey().getName())
.append('=')
.append(entry.getValue().toString());
}
toString.append(')');
return toString.toString();
}
/**
* Returns the hash code of the represented annotation.
*
* @return The hash code of the represented annotation.
*/
private int hashCodeRepresentation() {
int hashCode = 0;
for (Map.Entry<Method, AnnotationValue.Loaded<?>> entry : values.entrySet()) {
if (!entry.getValue().getState().isDefined()) {
continue;
}
hashCode += (127 * entry.getKey().getName().hashCode()) ^ entry.getValue().hashCode();
}
return hashCode;
}
/**
* Checks if another instance is equal to this instance.
*
* @param self The annotation proxy instance.
* @param other The instance to be examined for equality to the represented instance.
* @return {@code true} if the given instance is equal to the represented instance.
*/
private boolean equalsRepresentation(Object self, Object other) {
if (self == other) {
return true;
} else if (!annotationType.isInstance(other)) {
return false;
} else if (Proxy.isProxyClass(other.getClass())) {
InvocationHandler invocationHandler = Proxy.getInvocationHandler(other);
if (invocationHandler instanceof AnnotationInvocationHandler) {
return invocationHandler.equals(this);
}
}
try {
for (Map.Entry<Method, AnnotationValue.Loaded<?>> entry : values.entrySet()) {
try {
if (!entry.getValue().represents(entry.getKey().invoke(other, NO_ARGUMENTS))) {
return false;
}
} catch (RuntimeException exception) {
return false; // Incomplete annotations are not equal to one another.
}
}
return true;
} catch (InvocationTargetException ignored) {
return false;
} catch (IllegalAccessException exception) {
throw new IllegalStateException("Could not access annotation property", exception);
}
}
@Override
public int hashCode() {
int result = annotationType.hashCode();
result = 31 * result + values.hashCode();
for (Map.Entry<Method, ?> entry : values.entrySet()) {
result = 31 * result + entry.getValue().hashCode();
}
return result;
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
} else if (!(other instanceof AnnotationInvocationHandler)) {
return false;
}
AnnotationInvocationHandler that = (AnnotationInvocationHandler) other;
if (!annotationType.equals(that.annotationType)) {
return false;
}
for (Map.Entry<Method, AnnotationValue.Loaded<?>> entry : values.entrySet()) {
if (!entry.getValue().equals(that.values.get(entry.getKey()))) {
return false;
}
}
return true;
}
/**
* Represents a missing annotation property which is not represented by a default value.
*/
protected static class MissingValue extends AnnotationValue.Loaded.AbstractBase<Void> implements AnnotationValue<Void, Void> {
/**
* The annotation type.
*/
private final Class<? extends Annotation> annotationType;
/**
* The name of the property without an annotation value.
*/
private final String property;
/**
* Creates a new representation for a missing annotation property.
*
* @param annotationType The annotation type.
* @param property The name of the property without an annotation value.
*/
protected MissingValue(Class<? extends Annotation> annotationType, String property) {
this.annotationType = annotationType;
this.property = property;
}
/**
* Creates a missing value for the supplied annotation property.
*
* @param method A method representing an annotation property.
* @return An annotation value for a missing property.
*/
@SuppressWarnings("unchecked")
protected static AnnotationValue<?, ?> of(Method method) {
return new MissingValue((Class<? extends Annotation>) method.getDeclaringClass(), method.getName());
}
/**
* {@inheritDoc}
*/
public State getState() {
return State.UNDEFINED;
}
/**
* {@inheritDoc}
*/
public boolean represents(Object value) {
return false;
}
/**
* {@inheritDoc}
*/
public Loaded<Void> load(ClassLoader classLoader) {
return this;
}
/**
* {@inheritDoc}
*/
public Loaded<Void> loadSilent(ClassLoader classLoader) {
return this;
}
/**
* {@inheritDoc}
*/
public Void resolve() {
throw new IncompleteAnnotationException(annotationType, property);
}
/* does intentionally not implement hashCode, equals and toString */
}
}
在 JDK 1.8 及其后的版本中,sun.reflect
及其下的类(如 AnnotationInvocationHandler
)通常不被包含在 src.zip
文件中,这是因为它们属于内部实现类,并非公开的API。sun.*
包下的类是 Java 平台的内部实现细节,通常不鼓励或不建议开发者直接使用,因为它们可能会在不同的 JDK 版本或实现中有所不同,导致代码的可移植性和稳定性问题。
如果你确实需要查看这些类的源码(例如,为了调试或学习),你可以考虑以下几种方法:
sun.reflect.annotation.AnnotationInvocationHandler
的源码。src.zip
更为方便,因为 IDE 可以自动处理版本匹配和更新。.jar
或 .class
文件),你可以使用反编译器(如 JD-GUI、Procyon 或 CFR)来查看这些类的源码。但请注意,反编译的源码可能不如原始源码易于阅读和理解。注意:由于 sun.*
包下的类是内部实现细节,因此你应该尽量避免在应用程序代码中使用它们。如果你的代码依赖于这些类,那么它可能会在未来的 JDK 版本中变得不可用或不稳定。
问题内容: 我知道每次键入字符串文字时,字符串池中都会引用相同的String对象。 但是,为什么String API不包含,所以我可以使用引用? 至少,这将节省编译时间,因为编译器将知道引用现有的String,而不必检查是否已创建它以进行重用,对吗?我个人认为,字符串文字(尤其是很小的文字)在许多情况下是一种“代码异味”。 那么是否没有String.Empty背后的宏伟设计原因,还是语言创建者根本
问题内容: 在Java中,有和接口。两者都属于Java的标准框架,并提供了一种访问元素的分类方法。 但是,据我了解没有。你可以用来对列表进行排序。 知道为什么要这样设计吗? 问题答案: 列表迭代器首先确保你以列表的内部顺序(也称为插入顺序)获取列表的元素。更具体地说,它是按照插入元素的顺序或操作列表的方式进行的。排序可以看作是对数据结构的一种操作,有几种方法可以对列表进行排序。 我将按照自己的见解
问题内容: 我最近发现了这个习惯用法,我想知道是否有我想念的东西。我从未见过使用过它。我几乎使用过的几乎所有Java代码都倾向于将数据插入字符串或缓冲区,而不是像本示例那样(例如,使用HttpClient和XML API): 该代码使用Unix管道样式的技术来防止将XML数据的多个副本保留在内存中。它使用HTTP Post输出流和DOM Load / Save API将XML文档序列化为HTTP请
问题内容: 恐怕这是一个愚蠢的问题。 有谁能告诉我为什么没有对立的东西? 除了“因为根本就没有”以外,还有其他原因吗? 我应该创建自己的一个吗?还是我想念其他东西? 更新资料 在哪里使用?我正在编写一个使用大量消费者和供应商的图书馆。我成功地写了一行,并且遇到一种情况,期望消费者接受来自方法结果的布尔值。说什么 问题答案: 并且需要避免开销自动装箱每个值。处理原始图元更有效。但是,对于布尔值和字节
Java中的本质上是不可靠的。具体地说,我对接口的最大问题是,它需要一个不定义方法本身的方法行为。因此,如果遍历一个列表,您必须使用反射来访问它定义的行为。然而,在Java8中,我们现在有了默认方法,现在我问为什么在中没有默认的方法。 我理解为什么接口不能默认对象方法,但是,这是一个明确的设计决定,所以可以做出例外。 我有点想弃用并将其内部代码更改为类似以下内容: 然后继续使用使作为中的默认方法的
正如你所看到的,詹金斯没有找到我的资源。 我错过了什么?