Class源码

news2024/11/19 13:23:59

介绍

如果想要在程序运行阶段访问某个类的所有信息,并支持修改类的状态或者行为的话,肯定会用到反射,而反射靠的就是Class类。

通过Class类可以获取类的实例,构造方法,字段,成员方法,接口等信息。获取之后可以通过API进行相应的操作。

public final class Class<T> implements java.io.Serializable,
                              GenericDeclaration,
                              Type,
                              AnnotatedElement

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NGXRMgsz-1685746810777)(null)]

常量&变量

    //标识注解类型
    private static final int ANNOTATION= 0x00002000;
    //标识枚举类型
    private static final int ENUM      = 0x00004000;
    //表示该class文件并非由Java源代码所生成
    private static final int SYNTHETIC = 0x00001000;
    //注册本地方法
    private static native void registerNatives();
    static {
        registerNatives();
    }

    //缓存构造器
    private volatile transient Constructor<T> cachedConstructor;
    //调用者的缓存构造器
    private volatile transient Class<?>       newInstanceCallerCache;
    
    // cache the name to reduce the number of calls into the VM
    //实体的名称
    private transient String name;
    private native String getName0();
    
    // Package-private to allow ClassLoader access
    ClassLoader getClassLoader0() { return classLoader; }

    // Initialized in JVM not by private constructor
    // This field is filtered from reflection access, i.e. getDeclaredField
    // will throw NoSuchFieldException
    //类加载器
    private final ClassLoader classLoader;
    
    /** protection domain returned when the internal domain is null */
    //null值的安全返回
    private static java.security.ProtectionDomain allPermDomain;
    
    /**
     * Reflection support.
     */

    // Caches for certain reflective results
    //缓存反射结果
    private static boolean useCaches = true;
    
    //反射信息
    private volatile transient SoftReference<ReflectionData<T>> reflectionData;

    // Incremented by the VM on each call to JVM TI RedefineClasses()
    // that redefines this class or a superclass.
    //每次调用JVM时由VM递增
    private volatile transient int classRedefinedCount = 0;
    

    // Generic signature handling
    private native String getGenericSignature0();

    // Generic info repository; lazily initialized
    //通用信息
    private volatile transient ClassRepository genericInfo;
    
    
    /** use serialVersionUID from JDK 1.1 for interoperability */
    //序列化版本号
    private static final long serialVersionUID = 3206093459760846163L;


    /**
     * Class Class is special cased within the Serialization Stream Protocol.
     *
     * A Class instance is written initially into an ObjectOutputStream in the
     * following format:
     * <pre>
     *      {@code TC_CLASS} ClassDescriptor
     *      A ClassDescriptor is a special cased serialization of
     *      a {@code java.io.ObjectStreamClass} instance.
     * </pre>
     * A new handle is generated for the initial time the class descriptor
     * is written into the stream. Future references to the class descriptor
     * are written as references to the initial class descriptor instance.
     *
     * @see java.io.ObjectStreamClass
     */
    private static final ObjectStreamField[] serialPersistentFields =
        new ObjectStreamField[0];
        

    //反射工厂
    private static ReflectionFactory reflectionFactory;

    // To be able to query system properties as soon as they're available
    //是否初始化
    private static boolean initted = false;
    private static void checkInitted() {
        if (initted) return;
        AccessController.doPrivileged(new PrivilegedAction<Void>() {
                public Void run() {
                    // Tests to ensure the system properties table is fully
                    // initialized. This is needed because reflection code is
                    // called very early in the initialization process (before
                    // command-line arguments have been parsed and therefore
                    // these user-settable properties installed.) We assume that
                    // if System.out is non-null then the System class has been
                    // fully initialized and that the bulk of the startup code
                    // has been run.

                    if (System.out == null) {
                        // java.lang.System not yet fully initialized
                        return null;
                    }

                    // Doesn't use Boolean.getBoolean to avoid class init.
                    String val =
                        System.getProperty("sun.reflect.noCaches");
                    if (val != null && val.equals("true")) {
                        useCaches = false;
                    }

                    initted = true;
                    return null;
                }
            });
    }

    //枚举类常量 null
    private volatile transient T[] enumConstants = null;
    
    //枚举类常量目录
    private volatile transient Map<String, T> enumConstantDirectory = null;
    
    // Annotations cache
    @SuppressWarnings("UnusedDeclaration")
    //注解数据
    private volatile transient AnnotationData annotationData;
    
    @SuppressWarnings("UnusedDeclaration")
    //注解类型
    private volatile transient AnnotationType annotationType;
    
    /* Backing store of user-defined values pertaining to this class.
     * Maintained by the ClassValue class.
     */
    transient ClassValue.ClassValueMap classValueMap;

构造方法

    /*
     * Private constructor. Only the Java Virtual Machine creates Class objects.
     * This constructor is not used and prevents the default constructor being
     * generated.
     *只能由java虚拟机创建对象
     */
    private Class(ClassLoader loader) {
        // Initialize final field for classLoader.  The initialization value of non-null
        // prevents future JIT optimizations from assuming this final field is null.
        classLoader = loader;
    }

Class并不能直接通过new Class()获取实例。那么应该如何获取呢?

//直接通过类的静态变量来获取
Class<Integer> intClass = Integer.class;

//通过实例变量的getClass方法
Integer integer = new Integer(0);
Class<? extends Integer> aClass = integer.getClass();

//通过Class.forName("类的全限定名")
Class<?> aClass1 = Class.forName("java.lang.Integer");

常用方法

forName

    /**
     * Returns the {@code Class} object associated with the class or
     * interface with the given string name.  Invoking this method is
     * equivalent to:
     *
     * <blockquote>
     *  {@code Class.forName(className, true, currentLoader)}
     * </blockquote>
     *
     * where {@code currentLoader} denotes the defining class loader of
     * the current class.
     *
     * <p> For example, the following code fragment returns the
     * runtime {@code Class} descriptor for the class named
     * {@code java.lang.Thread}:
     *
     * <blockquote>
     *   {@code Class t = Class.forName("java.lang.Thread")}
     * </blockquote>
     * <p>
     * A call to {@code forName("X")} causes the class named
     * {@code X} to be initialized.
     *
     * @param      className   the fully qualified name of the desired class.
     * @return     the {@code Class} object for the class with the
     *             specified name.
     * @exception LinkageError if the linkage fails
     * @exception ExceptionInInitializerError if the initialization provoked
     *            by this method fails
     * @exception ClassNotFoundException if the class cannot be located
     * 手动加载一个类,
     */
    @CallerSensitive
    public static Class<?> forName(String className)
                throws ClassNotFoundException {
        Class<?> caller = Reflection.getCallerClass();
        return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
    }


    /**
     * Returns the {@code Class} object associated with the class or
     * interface with the given string name, using the given class loader.
     * Given the fully qualified name for a class or interface (in the same
     * format returned by {@code getName}) this method attempts to
     * locate, load, and link the class or interface.  The specified class
     * loader is used to load the class or interface.  If the parameter
     * {@code loader} is null, the class is loaded through the bootstrap
     * class loader.  The class is initialized only if the
     * {@code initialize} parameter is {@code true} and if it has
     * not been initialized earlier.
     *
     * <p> If {@code name} denotes a primitive type or void, an attempt
     * will be made to locate a user-defined class in the unnamed package whose
     * name is {@code name}. Therefore, this method cannot be used to
     * obtain any of the {@code Class} objects representing primitive
     * types or void.
     *
     * <p> If {@code name} denotes an array class, the component type of
     * the array class is loaded but not initialized.
     *
     * <p> For example, in an instance method the expression:
     *
     * <blockquote>
     *  {@code Class.forName("Foo")}
     * </blockquote>
     *
     * is equivalent to:
     *
     * <blockquote>
     *  {@code Class.forName("Foo", true, this.getClass().getClassLoader())}
     * </blockquote>
     *
     * Note that this method throws errors related to loading, linking or
     * initializing as specified in Sections 12.2, 12.3 and 12.4 of <em>The
     * Java Language Specification</em>.
     * Note that this method does not check whether the requested class
     * is accessible to its caller.
     *
     * <p> If the {@code loader} is {@code null}, and a security
     * manager is present, and the caller's class loader is not null, then this
     * method calls the security manager's {@code checkPermission} method
     * with a {@code RuntimePermission("getClassLoader")} permission to
     * ensure it's ok to access the bootstrap class loader.
     *
     * @param name       fully qualified name of the desired class
     * @param initialize if {@code true} the class will be initialized.
     *                   See Section 12.4 of <em>The Java Language Specification</em>.
     * @param loader     class loader from which the class must be loaded
     * @return           class object representing the desired class
     *
     * @exception LinkageError if the linkage fails
     * @exception ExceptionInInitializerError if the initialization provoked
     *            by this method fails
     * @exception ClassNotFoundException if the class cannot be located by
     *            the specified class loader
     *
     * @see       java.lang.Class#forName(String)
     * @see       java.lang.ClassLoader
     * @since     1.2
     * boolean initialize 是否对类进行初始化
     */
    @CallerSensitive
    public static Class<?> forName(String name, boolean initialize,
                                   ClassLoader loader)
        throws ClassNotFoundException
    {
        Class<?> caller = null;
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            // Reflective call to get caller class is only needed if a security manager
            // is present.  Avoid the overhead of making this call otherwise.
            caller = Reflection.getCallerClass();
            if (sun.misc.VM.isSystemDomainLoader(loader)) {
                ClassLoader ccl = ClassLoader.getClassLoader(caller);
                if (!sun.misc.VM.isSystemDomainLoader(ccl)) {
                    sm.checkPermission(
                        SecurityConstants.GET_CLASSLOADER_PERMISSION);
                }
            }
        }
        return forName0(name, initialize, loader, caller);
    }

    /** Called after security check for system loader access checks have been made. */
    private static native Class<?> forName0(String name, boolean initialize,
                                            ClassLoader loader,
                                            Class<?> caller)
        throws ClassNotFoundException;

在使用反射的时候,Class.forName是最常用的一种方式。而Class.forName底层会指向forName0这个本地方法

参数:

(1)name:类的全限定名

(2)initialize:是否初始化这个类

(3)loader:类加载器

(4)caller:调用Class.forName所在类的Class,比如A类代码块里有Class.forName,那么caller就是A的class实例。

getConstructors

    /**
     * Returns an array containing {@code Constructor} objects reflecting
     * all the public constructors of the class represented by this
     * {@code Class} object.  An array of length 0 is returned if the
     * class has no public constructors, or if the class is an array class, or
     * if the class reflects a primitive type or void.
     *
     * Note that while this method returns an array of {@code
     * Constructor<T>} objects (that is an array of constructors from
     * this class), the return type of this method is {@code
     * Constructor<?>[]} and <em>not</em> {@code Constructor<T>[]} as
     * might be expected.  This less informative return type is
     * necessary since after being returned from this method, the
     * array could be modified to hold {@code Constructor} objects for
     * different classes, which would violate the type guarantees of
     * {@code Constructor<T>[]}.
     *
     * @return the array of {@code Constructor} objects representing the
     *         public constructors of this class
     * @throws SecurityException
     *         If a security manager, <i>s</i>, is present and
     *         the caller's class loader is not the same as or an
     *         ancestor of the class loader for the current class and
     *         invocation of {@link SecurityManager#checkPackageAccess
     *         s.checkPackageAccess()} denies access to the package
     *         of this class.
     *
     * @since JDK1.1
     * 返回构造函数组成的数据
     */
    @CallerSensitive
    public Constructor<?>[] getConstructors() throws SecurityException {
        //判断是否有访问权限
        checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
        //获取到声明的构造方法,并拷贝一份构造方法
        return copyConstructors(privateGetDeclaredConstructors(true));
    }

privateGetDeclaredConstructors()

    // Returns an array of "root" constructors. These Constructor
    // objects must NOT be propagated to the outside world, but must
    // instead be copied via ReflectionFactory.copyConstructor.
    private Constructor<T>[] privateGetDeclaredConstructors(boolean publicOnly) {
        //判断是否配置了useCached属性
        checkInitted();
        Constructor<T>[] res;
        //获取缓存当中的数据
        ReflectionData<T> rd = reflectionData();
        if (rd != null) {
            //返回缓存当中的构造方法 根据publicOnly决定是共有还是私有的构造方法
            res = publicOnly ? rd.publicConstructors : rd.declaredConstructors;
            if (res != null) return res;
        }
        // No cached value available; request value from VM
        if (isInterface()) {
            //直接生成一个数组长度为0的Constructor数组  因为接口没有构造方法
            @SuppressWarnings("unchecked")
            Constructor<T>[] temporaryRes = (Constructor<T>[]) new Constructor<?>[0];
            res = temporaryRes;
        } else {
            //从JVM当中读取数据
            res = getDeclaredConstructors0(publicOnly);
        }
        if (rd != null) {
            //更新缓存reflectionData当中的构造方法
            if (publicOnly) {
                rd.publicConstructors = res;
            } else {
                rd.declaredConstructors = res;
            }
        }
        return res;
    }
reflectionData
    // Lazily create and cache ReflectionData
    //创建和缓存反射获得的数据
    private ReflectionData<T> reflectionData() {
        //获取当前reflectionData
        SoftReference<ReflectionData<T>> reflectionData = this.reflectionData;
        int classRedefinedCount = this.classRedefinedCount;
        ReflectionData<T> rd;
        //如果可以使用缓存,并且缓存当中的数据不为null,而且缓存没有失效,(缓存当中redefinedCount等于classRedefinedCount的值)
        if (useCaches &&
            reflectionData != null &&
            (rd = reflectionData.get()) != null &&
            rd.redefinedCount == classRedefinedCount) {
            //直接返回缓存当中的reflectionData
            return rd;
        }
        // else no SoftReference or cleared SoftReference or stale ReflectionData
        // -> create and replace new instance
        //创建新的reflectionData,并保存到缓存当中去
        return newReflectionData(reflectionData, classRedefinedCount);
    }
newReflectionData
    private ReflectionData<T> newReflectionData(SoftReference<ReflectionData<T>> oldReflectionData,
                                                int classRedefinedCount) {
        //不使用缓存,直接返回
        if (!useCaches) return null;
        //while + cas
        while (true) {
            //创建新的ReflectionData
            ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount);
            // try to CAS it...
            //更新成功,返回
            if (Atomic.casReflectionData(this, oldReflectionData, new SoftReference<>(rd))) {
                return rd;
            }
            // else retry
            //否则获得旧的reflectionData和classRedefinedCount的值
            oldReflectionData = this.reflectionData;
            classRedefinedCount = this.classRedefinedCount;
            //如果旧的值不为null, 并且缓存未失效,说明其他线程更新成功了
            if (oldReflectionData != null &&
                (rd = oldReflectionData.get()) != null &&
                rd.redefinedCount == classRedefinedCount) {
                //直接返回
                return rd;
            }
        }
    }

newInstance

Constructor.java

获取到Constructor之后,可以通过newInstance的方式获取到实例方法

Constructor.java
   /**
     * Uses the constructor represented by this {@code Constructor} object to
     * create and initialize a new instance of the constructor's
     * declaring class, with the specified initialization parameters.
     * Individual parameters are automatically unwrapped to match
     * primitive formal parameters, and both primitive and reference
     * parameters are subject to method invocation conversions as necessary.
     *
     * <p>If the number of formal parameters required by the underlying constructor
     * is 0, the supplied {@code initargs} array may be of length 0 or null.
     *
     * <p>If the constructor's declaring class is an inner class in a
     * non-static context, the first argument to the constructor needs
     * to be the enclosing instance; see section 15.9.3 of
     * <cite>The Java&trade; Language Specification</cite>.
     *
     * <p>If the required access and argument checks succeed and the
     * instantiation will proceed, the constructor's declaring class
     * is initialized if it has not already been initialized.
     *
     * <p>If the constructor completes normally, returns the newly
     * created and initialized instance.
     *
     * @param initargs array of objects to be passed as arguments to
     * the constructor call; values of primitive types are wrapped in
     * a wrapper object of the appropriate type (e.g. a {@code float}
     * in a {@link java.lang.Float Float})
     *
     * @return a new object created by calling the constructor
     * this object represents
     *
     * @exception IllegalAccessException    if this {@code Constructor} object
     *              is enforcing Java language access control and the underlying
     *              constructor is inaccessible.
     * @exception IllegalArgumentException  if the number of actual
     *              and formal parameters differ; if an unwrapping
     *              conversion for primitive arguments fails; or if,
     *              after possible unwrapping, a parameter value
     *              cannot be converted to the corresponding formal
     *              parameter type by a method invocation conversion; if
     *              this constructor pertains to an enum type.
     * @exception InstantiationException    if the class that declares the
     *              underlying constructor represents an abstract class.
     * @exception InvocationTargetException if the underlying constructor
     *              throws an exception.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     *  获取到实例方法
     */
    @CallerSensitive
    public T newInstance(Object ... initargs)
        throws InstantiationException, IllegalAccessException,
               IllegalArgumentException, InvocationTargetException
    {
        //判断语言级别的访问权限是否被覆盖
        if (!override) {
            //没有被覆盖需要检查是否有访问权限
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, null, modifiers);
            }
        }
        //判断是否为枚举类型
        if ((clazz.getModifiers() & Modifier.ENUM) != 0)
            //如果是枚举类型不能通过反射创建
            throw new IllegalArgumentException("Cannot reflectively create enum objects");
        //获取constructorAccessor
        ConstructorAccessor ca = constructorAccessor;   // read volatile
        if (ca == null) {
            //如果为null, 通过acquireConstructorAccessor获取
            ca = acquireConstructorAccessor();
        }
        //通过ConstructorAccessor创建实例对象
        @SuppressWarnings("unchecked")
        T inst = (T) ca.newInstance(initargs);
        return inst;
    }

acquireConstructorAccessor

构建ConstructorAccessor

Constructor.java 
     // NOTE that there is no synchronization used here. It is correct
    // (though not efficient) to generate more than one
    // ConstructorAccessor for a given Constructor. However, avoiding
    // synchronization will probably make the implementation more
    // scalable.
    private ConstructorAccessor acquireConstructorAccessor() {
        // First check to see if one has been created yet, and take it
        // if so.
        ConstructorAccessor tmp = null;
        if (root != null) tmp = root.getConstructorAccessor();
        if (tmp != null) {
            //先判断是否已经创建了ConstructorAccessor 如果已经创建了,直接返回获取就可以
            constructorAccessor = tmp;
        } else {
            // Otherwise fabricate one and propagate it up to the root
            //通过reflectionFactory来创建一个新的ConstructorAccessor
            tmp = reflectionFactory.newConstructorAccessor(this);
            //设置当前Class对象当中的ConstructorAccessor对象
            setConstructorAccessor(tmp);
        }

        return tmp;
    }

getDeclaredMethod

获取指定的Method对象方法

    /**
     * Returns a {@code Method} object that reflects the specified
     * declared method of the class or interface represented by this
     * {@code Class} object. The {@code name} parameter is a
     * {@code String} that specifies the simple name of the desired
     * method, and the {@code parameterTypes} parameter is an array of
     * {@code Class} objects that identify the method's formal parameter
     * types, in declared order.  If more than one method with the same
     * parameter types is declared in a class, and one of these methods has a
     * return type that is more specific than any of the others, that method is
     * returned; otherwise one of the methods is chosen arbitrarily.  If the
     * name is "&lt;init&gt;"or "&lt;clinit&gt;" a {@code NoSuchMethodException}
     * is raised.
     *
     * <p> If this {@code Class} object represents an array type, then this
     * method does not find the {@code clone()} method.
     *
     * @param name the name of the method
     * @param parameterTypes the parameter array
     * @return  the {@code Method} object for the method of this class
     *          matching the specified name and parameters
     * @throws  NoSuchMethodException if a matching method is not found.
     * @throws  NullPointerException if {@code name} is {@code null}
     * @throws  SecurityException
     *          If a security manager, <i>s</i>, is present and any of the
     *          following conditions is met:
     *
     *          <ul>
     *
     *          <li> the caller's class loader is not the same as the
     *          class loader of this class and invocation of
     *          {@link SecurityManager#checkPermission
     *          s.checkPermission} method with
     *          {@code RuntimePermission("accessDeclaredMembers")}
     *          denies access to the declared method
     *
     *          <li> the caller's class loader is not the same as or an
     *          ancestor of the class loader for the current class and
     *          invocation of {@link SecurityManager#checkPackageAccess
     *          s.checkPackageAccess()} denies access to the package
     *          of this class
     *
     *          </ul>
     *
     * @jls 8.2 Class Members
     * @jls 8.4 Method Declarations
     * @since JDK1.1
     * 获取指定的Method对象方法
     */
    @CallerSensitive
    public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
        throws NoSuchMethodException, SecurityException {
        //判断当前method是否有访问权限
        checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
        //privateGetDeclaredMethods获取到当前所声明的所有方法
        //根据当前传递的方法名和参数类型从声明的方法中找到匹配的方法
        Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
        if (method == null) {
            throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
        }
        //返回
        return method;
    }

privateGetDeclaredMethods

    // Returns an array of "root" methods. These Method objects must NOT
    // be propagated to the outside world, but must instead be copied
    // via ReflectionFactory.copyMethod.
    //获取类中声明方法具体的实现
    //publicOnly 是否只获取public方法
    private Method[] privateGetDeclaredMethods(boolean publicOnly) {
        //等待系统内部类初始化完成,系统属性(sun.reflect.noCaches)被解析完成
        checkInitted();
        Method[] res;
        //判断当前是否有配置信息
        ReflectionData<T> rd = reflectionData();
        if (rd != null) {
            //从缓存中获取数据
            res = publicOnly ? rd.declaredPublicMethods : rd.declaredMethods;
            if (res != null) return res;
        }
        // No cached value available; request value from VM
        //从JVM当中读取数据  getDeclaredMethods0(publicOnly) 使用native方式读取methods数组对象
        res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly));
        if (rd != null) {
            //将缓存当中的数据更新
            if (publicOnly) {
                rd.declaredPublicMethods = res;
            } else {
                rd.declaredMethods = res;
            }
        }
        return res;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/603843.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络编程知识点总结(3)

socket 服务器的开发步骤和代码实现 1.创建套接字 socket()函数 int socket(int domain, int type, int protocol); domain: 指明所使用的协议族&#xff0c;通常为 AF_INET&#xff0c;表示互联网协议族(TCP/IP 协议族)AF_INET IPv4因特网域. AF_INET6 IPv6 因特网域 AF_U…

屏幕录制安卓应用被发现在监视用户

据 ESET 的研究人员称&#xff0c;一款在 Google Play 商店中下载量超过 50,000 次的屏幕录像机应用程序被发现使用设备的麦克风悄悄地录制音频并窃取文件&#xff0c;这表明它可能是间谍活动的一部分。 iRecorder 是一个合法的应用程序&#xff0c;于 2021 年 9 月可用&#…

chatgpt赋能python:Python动态函数介绍

Python动态函数介绍 Python是一种高级编程语言&#xff0c;它支持动态函数。动态函数就是在Python中可以在运行时创建函数。这意味着编程者可以在编写代码时不必事先定义所有函数&#xff0c;而是可以通过Python函数来创建函数。 Python动态函数的一个好处是可以轻松地编写可…

chatgpt赋能python:Python动态列表介绍

Python动态列表介绍 Python是一种常用的高级编程语言&#xff0c;它支持多种数据结构&#xff0c;其中包括列表。以Python中的列表为例&#xff0c;本文将详细介绍Python动态列表的特点和用途。 Python中的列表 在Python中&#xff0c;列表就是一组由逗号分隔&#xff0c;放…

基于PyQt5的图形化界面开发——队列动画演示

目录 0. 前言1. 了解队列2. 代码实现3. 效果演示其他PyQt5文章 0. 前言 本文使用PyQt5制作图形化界面演示数据结构中的队列操作&#xff0c;与上一节队列动画相对应 基于PyQt5的图形化界面开发——队列动画演示 操作系统&#xff1a;Windows10 专业版 开发环境&#xff1a;P…

javascript基础十六:Ajax 原理是什么?如何实现?

一、是什么 AJAX全称(Async Javascript and XML) 即异步的JavaScript 和XML&#xff0c;是一种创建交互式网页应用的网页开发技术&#xff0c;可以在不重新加载整个网页的情况下&#xff0c;与服务器交换数据&#xff0c;并且更新部分网页 Ajax的原理简单来说通过XmlHttpRequ…

Linux编辑器,开机重启,用户注销,用户管理 常用命令

Linux 实操篇- Vi 和Vim 编辑器 vi 和vim 的基本介绍 Linux 系统会内置vi 文本编辑器 Vim 具有程序编辑的能力&#xff0c;可以看做是Vi 的增强版本&#xff0c;可以主动的以字体颜色辨别语法的正确性&#xff0c;方便程序设计。 代码补完、编译及错误跳转等方便编程的功能特…

环境感知算法——4.RandLA-Net基于SemanticKITTI训练

1.前言 RandLA-Net&#xff08;Random Sampling and Local Feature Aggregator Network&#xff09;是一种处理点云数据的神经网络结构&#xff0c;采用随机采样&#xff08;Random Sampling, RS&#xff09;以降低点云密度并减少计算量。尽管随机采样可能会丢掉一些有用的信息…

【 STM32实例 】 智能小车的红外循迹

文章目录 前言一、硬件选择与连接1. STM32F103C8T6最小系统板2. L298N双路电机驱动3. 红外循迹模块 二、环境配置1. Device2. Output3. C/C4. Debug 三、项目管理与代码实现1. 项目结构2. 工程管理3. 具体文件xunji.cxunji.hmain.c 总结项目源码 前言 这篇文章我主要讲的是让基…

chatgpt赋能python:Python加颜色代码-提高代码可读性和吸引力的简单技巧

Python加颜色代码 - 提高代码可读性和吸引力的简单技巧 在编写Python代码时&#xff0c;您可能已经注意到&#xff0c;有时候需要强调某些部分&#xff0c;以使其更易于阅读和理解。这时候&#xff0c;您可以使用加颜色代码来增强代码的可读性和吸引力。在本文中&#xff0c;我…

Opencv项目实战:基于dlib的人脸关键点检测

文章目录 一、项目简介二、环境配置2.1、dlib人脸检测器&#xff1a;dlib.get_frontal_face_detector()2.2、dlib关键点定位工具&#xff1a;shape_predictor_68_face_landmarks.dat 三、项目实战 一、项目简介 该项目基于dlib模块提供的人脸检测器以及关键点定位工具完成。首…

大数据:hive数据库的操作语法,数据表,内部表,external外部表,数据导入导出load,insert

大数据&#xff1a; 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c;oracle&#xff0c;尤其sql要学&#x…

chatgpt赋能python:关于Python中打开文件的语句详解

关于Python中打开文件的语句详解 在Python中&#xff0c;打开文件是一项常见的任务&#xff0c;可以用于读写文件和进行日志记录。本文将介绍Python中打开文件的语句&#xff0c;并提供一些实用技巧&#xff0c;以便方便地管理文件。 为什么需要打开文件&#xff1f; 在计算…

【动态规划】通配符匹配与正则表达式匹配

文章目录 一、通配符匹配1.1 思路分析1.2 初始化处理1.3 代码1.4 优化 二、正则表达式匹配2.1 思路分析2.2 初始化设置2.3 代码 一、通配符匹配 题目描述&#xff1a; 给你一个输入字符串 (s) 和一个字符模式 &#xff0c;请你实现一个支持 ‘?’ 和 ‘*’ 匹配规则的通配符…

如何在Github上免费部署网站

如何在Github上免费部署静态网站 背景一、新建仓库&#xff08;github账号的需要注册&#xff09;二、下载仓库三、将内容上传到远程仓库里四、启动Page服务 背景 部署网站需要服务器&#xff0c;但是如果你只是部署静态网站就可以蹭Github上的免费服务器。因为发现现在的过程…

基于springboot+Redis的前后端分离项目(一)-【黑马点评】

&#x1f381;&#x1f381;资源文件分享 链接&#xff1a;https://pan.baidu.com/s/1189u6u4icQYHg_9_7ovWmA?pwdeh11 提取码&#xff1a;eh11 基于session和redis实现登录 &#xff08;一&#xff09;前言&#xff08;二&#xff09;导入资源&#xff08;三&#xff09;短信…

Spring数据库事务处理

数据库事务的基本知识 ACID 两类丢失更新 事务回滚丢失更新&#xff1a; 目前大部分数据库已经通过锁的机制来避免了事务回滚丢失更新。 数据库锁的机制&#xff1a; 锁可以分为乐观锁和悲观锁&#xff0c;而悲观锁又分为&#xff1a;读锁(共享锁)和写锁(排它锁)&#xff0c;…

chatgpt赋能python:使用Python制作动画的步骤和工具

使用Python制作动画的步骤和工具 Python不仅是一种流行的编程语言&#xff0c;还可以用于制作动画。本文将介绍一些基本步骤和工具&#xff0c;帮助你制作出精美的动画作品。 步骤一&#xff1a;选择一个好的动画框架 Python有很多强大的动画框架可以使用。其中一些最受欢迎…

chatgpt赋能python:Python删除目录下文件:介绍和方法

Python删除目录下文件&#xff1a;介绍和方法 在日常的开发和运维工作中&#xff0c;我们可能会需要删除某个目录下的一些文件。使用Python的好处在于其强大的处理能力和简单易用的语法。本文将介绍Python删除目录下文件的方法&#xff0c;并提供一些实用的代码示例。 使用os…

java-数组和方法

java-数组和方法 一、数组 1.1 概念 数组就是存储数据长度固定的容器&#xff0c;存储多个数据的数据类型要一致。 1.2 定义格式 第一种 数据类型 [] 数组名 例: int[] arr; double[] arr; char[] arr;第二种 数据类型 数组名[] 例: int arr[]; doubl…