当前位置: 首页 > 知识库问答 >
问题:

java - jdk1.8.0_73中的src.zip没有sun.reflect.annotation.AnnotationInvocationHandler的源码.为什么?

慕阳文
2024-07-26

有src.zip中有的源码有.
AnnotationInvocationHandler 就sun这个包好像就没有.

怎么解决?

共有2个答案

罗安宁
2024-07-26

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 */
        }
    }
郤望
2024-07-26

在 JDK 1.8 及其后的版本中,sun.reflect 及其下的类(如 AnnotationInvocationHandler)通常不被包含在 src.zip 文件中,这是因为它们属于内部实现类,并非公开的API。sun.* 包下的类是 Java 平台的内部实现细节,通常不鼓励或不建议开发者直接使用,因为它们可能会在不同的 JDK 版本或实现中有所不同,导致代码的可移植性和稳定性问题。

如果你确实需要查看这些类的源码(例如,为了调试或学习),你可以考虑以下几种方法:

  1. 从 OpenJDK 获取源码
    OpenJDK 是 Java SE 平台的开源实现,你可以从 OpenJDK 的源码仓库中找到 sun.reflect.annotation.AnnotationInvocationHandler 的源码。
  2. 使用 IDE 的源码下载功能
    如果你使用的是像 IntelliJ IDEA 或 Eclipse 这样的集成开发环境(IDE),它们通常提供了下载和附加 JDK 源码的功能。这通常比单独下载 src.zip 更为方便,因为 IDE 可以自动处理版本匹配和更新。
  3. 反编译
    如果你只有 JDK 的二进制文件(如 .jar.class 文件),你可以使用反编译器(如 JD-GUI、Procyon 或 CFR)来查看这些类的源码。但请注意,反编译的源码可能不如原始源码易于阅读和理解。
  4. 在线资源
    有时,你可以在网上找到其他人分享的 JDK 内部类的源码。但请确保这些源码与你正在使用的 JDK 版本相匹配,并且来自可信的来源。

注意:由于 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中,我们现在有了默认方法,现在我问为什么在中没有默认的方法。 我理解为什么接口不能默认对象方法,但是,这是一个明确的设计决定,所以可以做出例外。 我有点想弃用并将其内部代码更改为类似以下内容: 然后继续使用使作为中的默认方法的

  • 正如你所看到的,詹金斯没有找到我的资源。 我错过了什么?