zoukankan      html  css  js  c++  java
  • java8-Class

    Class主要封装对Class对象的操作。Class类实现Serializable,GenericDeclaration,Type,AnnotatedElement接口。

    GenericDeclaration : 所有声明类型变量实体的通用接口

     

    Type: Java所有类型的父接口,它包含原始类型,参数化类型,数组类型,类型变量,原始类型.

     

    注意参数化类型和类型变量的区别.

      1:A TypeVariable refers to the declaration of the type variable

      2:a ParametrizedType is a use of such a type

    注意下面这个代码

    public class View
    {
        public Collection<String> c;
    
        public static void main(String[] args) throws NoSuchFieldException, SecurityException
        {
            System.out.println(Collection.class.getTypeParameters()[0]); // E
            System.out.println(Collection.class.getTypeParameters()[0] instanceof TypeVariable); // true
            System.out.println(Collection.class.getTypeParameters()[0] instanceof ParameterizedType); // false
            Field field = View.class.getField("c");
            System.out.println(field.getGenericType()); // java.util.Collection<java.lang.String>
            System.out.println(field.getGenericType() instanceof TypeVariable); // false
            System.out.println(field.getGenericType() instanceof ParameterizedType); // true
        }
    
        public static class T<O>
        {
            O o;
        }
    
    }

    T newInstance()生成对应Class的实例,使用无参构造函数生成实例,注意下面这个代码。

    @CallerSensitive
        public T newInstance()
            throws InstantiationException, IllegalAccessException
        {
            if (System.getSecurityManager() != null) {
                checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
            }
    
            // NOTE: the following code may not be strictly correct under
            // the current Java memory model.
    
            // Constructor lookup
            if (cachedConstructor == null) {
                if (this == Class.class) {
                    throw new IllegalAccessException(
                        "Can not call newInstance() on the Class for java.lang.Class"
                    );
                }
                try {
                    Class<?>[] empty = {};
                    final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
                    // Disable accessibility checks on the constructor
                    // since we have to do the security check here anyway
                    // (the stack depth is wrong for the Constructor's
                    // security check to work)
                    java.security.AccessController.doPrivileged(
                        new java.security.PrivilegedAction<Void>() {
                            public Void run() {
                                    c.setAccessible(true);
                                    return null;
                                }
                            });
                    cachedConstructor = c;
                } catch (NoSuchMethodException e) {
                    throw (InstantiationException)
                        new InstantiationException(getName()).initCause(e);
                }
            }
            Constructor<T> tmpConstructor = cachedConstructor;
            // Security check (same as in java.lang.reflect.Constructor)
            int modifiers = tmpConstructor.getModifiers();
            if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                if (newInstanceCallerCache != caller) {
                    Reflection.ensureMemberAccess(caller, this, null, modifiers);
                    newInstanceCallerCache = caller;
                }
            }
            // Run constructor
            try {
                return tmpConstructor.newInstance((Object[])null);
            } catch (InvocationTargetException e) {
                Unsafe.getUnsafe().throwException(e.getTargetException());
                // Not reached
                return null;
            }
        }

    使用了一个cachedConstructor,并且这个属性是volatile属性。意思就是Class对象会缓存一个构造器,免得每次调用都去解析构造器。 

    newInstanceCallerCache 用于保存校验调用者权限缓存。如果caller没有改变,不用在用校验权限.

    Class类型isXXX方法的实现都是检查类的字节码格式,具体可以查看Java8的虚拟机规范定义的类文件格式.比如像这种

    public boolean isAnnotation() {
            return (getModifiers() & ANNOTATION) != 0;
        }

    getName()方法。也有一个缓存的name,防止每次都要调用虚拟机接口.

       public String getName() {
            String name = this.name;
            if (name == null)
                this.name = name = getName0();
            return name;
        }
    Element Type           Encoding
    boolean                 Z
    byte                    B
    char                    C
    class or interface     Lclassname;
    double                  D
    float                   F
    int                     I
    long                    J
    short                   S
    The class or interface name classname is the binary name of the class specified above.
    
    Examples:
    
     String.class.getName()
         returns "java.lang.String"
     byte.class.getName()
         returns "byte"
     (new Object[3]).getClass().getName()
         returns "[Ljava.lang.Object;"
     (new int[3][4][5][6][7][8][9]).getClass().getName()
         returns "[[[[[[[I"
     

    这个方法返回的是类的二进制名称。

    2. getClassLoader 返回此类的加载器,如果是启动类加载上来的,返回null.基本类型和Void都是返回null。

    3. getDeclaredXXX返回类所有声明的,getXXXX基本上只返回public的。

    4. getResourceAsStream 因为由启动类加载的类没有类加载器,委托给系统类加载器。参数的参数如果是绝对地址,不处理,如果不是绝对地址,那么就是当前包/resourceName

    5.为了加快速度,getXXX,getDeclaredXX会从缓存中获取.

    // Caches for certain reflective results
        private static boolean useCaches = true;
    
        // reflection data that might get invalidated when JVM TI RedefineClasses() is called
        private static class ReflectionData<T> {
            volatile Field[] declaredFields;
            volatile Field[] publicFields;
            volatile Method[] declaredMethods;
            volatile Method[] publicMethods;
            volatile Constructor<T>[] declaredConstructors;
            volatile Constructor<T>[] publicConstructors;
            // Intermediate results for getFields and getMethods
            volatile Field[] declaredPublicFields;
            volatile Method[] declaredPublicMethods;
            volatile Class<?>[] interfaces;
    
            // Value of classRedefinedCount when we created this ReflectionData instance
            final int redefinedCount;
    
            ReflectionData(int redefinedCount) {
                this.redefinedCount = redefinedCount;
            }
        }

    可以通过此系统变量来关闭反射缓存。

    sun.reflect.noCaches

     

     

  • 相关阅读:
    PHP实现发送模板消息(微信公众号版)
    laravel 跨域问题
    微信授权登录
    支付demo2
    支付demo1
    微信支付注意点
    微信支付方式区分
    debian,dietpi,linux中文乱码解决方法
    嵌入式应该深入专研STM32还是继续学习linux内核驱动呢?
    arduino下载ESP8266开发板的方法
  • 原文地址:https://www.cnblogs.com/shuiyonglewodezzzzz/p/11158620.html
Copyright © 2011-2022 走看看