<p><em>JSBENCH 不允许保存超过一定数量的字符或单词。我在异步获取随机单词时遇到了一些麻烦,所以您可以手动获取随机单词,并以这种方式使用工作台。</em></p> <h1>编辑:</h1> 什么是 Java类加载器?

好吧,我看了一篇维基文章。ClassLoader 加载类。好的。因此,如果我包含 jar 文件并导入,ClassLoader 会完成这项工作。

你原来的问题提到了“摇摆计时器”。如果事实上你的问题与 SWing 有关,那么你应该使用 SWing Timer 而不是 util。计时器。

我为什么要操心这个 ClassLoader? 我从来没有用过它,也不知道它的存在。

问题是,为什么存在 ClassLoader 类?还有,如何在实践中使用它?(我知道有这种情况)

60038 次浏览

阅读 Swing 教程中关于“ 如何使用计时器”的部分以获得更多信息。

摘自太阳 教程:

动机

将代码组合成可执行本机代码的过程称为链接——将单独编译的代码与共享库代码合并以创建可执行应用程序。这在诸如 Java 之类的动态编译编程语言中是不同的。在爪哇。Java 编译器生成的类文件保持原样,直到加载到 Java 虚拟机(JVM)中——换句话说,链接过程在运行时由 JVM 执行。根据需要将类加载到 JVM 中。当一个已加载的类依赖于另一个类时,那么该类也会被加载。

使用静态编译的编程语言(如 C 和 C + +)编写的应用程序被编译成本机特定指令,并保存为可执行文件。将代码组合成可执行本机代码的过程称为链接——将单独编译的代码与共享库代码合并以创建可执行应用程序。这在诸如 Java 之类的动态编译编程语言中是不同的。在爪哇。Java 编译器生成的类文件保持原样,直到加载到 Java 虚拟机(JVM)中——换句话说,链接过程在运行时由 JVM 执行。根据需要将类加载到 JVM 中。当一个已加载的类依赖于另一个类时,那么该类也会被加载。

启动 Java 应用程序时,要运行的第一个类(或应用程序的入口点)是具有名为 main ()的公共静态 void 方法的类。此类通常具有对其他类的引用,并且所有加载引用类的尝试都由类加载器执行。

启动 Java 应用程序时,要运行的第一个类(或应用程序的入口点)是具有名为 main ()的公共静态 void 方法的类。此类通常具有对其他类的引用,并且所有加载引用类的尝试都由类加载器执行。

要了解这种递归类装入以及一般类装入思想,请考虑以下简单类:

public class HelloApp {
public static void main(String argv[]) {
System.out.println("Aloha! Hello and Bye");
}
}

要了解这种递归类装入以及一般类装入思想,请考虑以下简单类:

public class HelloApp {
public static void main(String argv[]) {
System.out.println("Aloha! Hello and Bye");
}
}

如果您运行这个指定-verose: class 命令行选项的类,以便它打印正在加载的类,您将获得如下输出。注意,这只是部分输出,因为列表太长,无法在这里显示。

prmpt>java -verbose:class HelloApp






[Opened C:\Program Files\Java\jre1.5.0\lib\rt.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jsse.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jce.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\charsets.jar]
[Loaded java.lang.Object from shared objects file]
[Loaded java.io.Serializable from shared objects file]
[Loaded java.lang.Comparable from shared objects file]
[Loaded java.lang.CharSequence from shared objects file]
[Loaded java.lang.String from shared objects file]
[Loaded java.lang.reflect.GenericDeclaration from shared objects file]
[Loaded java.lang.reflect.Type from shared objects file]
[Loaded java.lang.reflect.AnnotatedElement from shared objects file]
[Loaded java.lang.Class from shared objects file]
[Loaded java.lang.Cloneable from shared objects file]
[Loaded java.lang.ClassLoader from shared objects file]
[Loaded java.lang.System from shared objects file]
[Loaded java.lang.Throwable from shared objects file]
.
.
.
[Loaded java.security.BasicPermissionCollection from shared objects file]
[Loaded java.security.Principal from shared objects file]
[Loaded java.security.cert.Certificate from shared objects file]
[Loaded HelloApp from file:/C:/classes/]
Aloha! Hello and Bye
[Loaded java.lang.Shutdown from shared objects file]
[Loaded java.lang.Shutdown$Lock from shared objects file]

如果您运行这个指定-verose: class 命令行选项的类,以便它打印正在加载的类,您将获得如下输出。注意,这只是部分输出,因为列表太长,无法在这里显示。

prmpt>java -verbose:class HelloApp






[Opened C:\Program Files\Java\jre1.5.0\lib\rt.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jsse.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jce.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\charsets.jar]
[Loaded java.lang.Object from shared objects file]
[Loaded java.io.Serializable from shared objects file]
[Loaded java.lang.Comparable from shared objects file]
[Loaded java.lang.CharSequence from shared objects file]
[Loaded java.lang.String from shared objects file]
[Loaded java.lang.reflect.GenericDeclaration from shared objects file]
[Loaded java.lang.reflect.Type from shared objects file]
[Loaded java.lang.reflect.AnnotatedElement from shared objects file]
[Loaded java.lang.Class from shared objects file]
[Loaded java.lang.Cloneable from shared objects file]
[Loaded java.lang.ClassLoader from shared objects file]
[Loaded java.lang.System from shared objects file]
[Loaded java.lang.Throwable from shared objects file]
.
.
.
[Loaded java.security.BasicPermissionCollection from shared objects file]
[Loaded java.security.Principal from shared objects file]
[Loaded java.security.cert.Certificate from shared objects file]
[Loaded HelloApp from file:/C:/classes/]
Aloha! Hello and Bye
[Loaded java.lang.Shutdown from shared objects file]
[Loaded java.lang.Shutdown$Lock from shared objects file]

如您所见,首先加载应用程序类(HelloApp)所需的 Java 运行时类。

如您所见,首先加载应用程序类(HelloApp)所需的 Java 运行时类。

Java2平台中的类装入器

Java2平台中的类装入器

Java 编程语言不断发展,使应用程序开发人员的日常生活变得更加轻松。这是通过提供 API 来实现的,这些 API 允许您专注于业务逻辑而不是基本机制的实现细节,从而简化了您的生活。为了反映 Java 平台的成熟度,最近将 J2SE 1.5更改为 J2SE 5.0,这一点很明显。

Java 编程语言不断发展,使应用程序开发人员的日常生活变得更加轻松。这是通过提供 API 来实现的,这些 API 允许您专注于业务逻辑而不是基本机制的实现细节,从而简化了您的生活。为了反映 Java 平台的成熟度,最近将 J2SE 1.5更改为 J2SE 5.0,这一点很明显。

从 JDK 1.2开始,内置在 JVM 中的引导类装入器负责装入 Java 运行时的类。这个类装入器只装入在引导类路径中找到的类,由于这些类是受信任的类,验证过程不会像对待不受信任的类那样执行。除了引导类装入器之外,JVM 还有一个负责从标准扩展 API 装入类的扩展类装入器,以及一个从通用类路径和应用程序类装入类的系统类装入器。

从 JDK 1.2开始,内置在 JVM 中的引导类装入器负责装入 Java 运行时的类。这个类装入器只装入在引导类路径中找到的类,由于这些类是受信任的类,验证过程不会像对待不受信任的类那样执行。除了引导类装入器之外,JVM 还有一个负责从标准扩展 API 装入类的扩展类装入器,以及一个从通用类路径和应用程序类装入类的系统类装入器。

因为有不止一个类装入器,所以它们在根是引导类装入器的树中表示。每个类装入器都有一个对其父类装入器的引用。当一个类装入器被要求装入一个类时,它会在尝试装入项目本身之前咨询它的父类装入器。父节点依次咨询其父节点,依此类推。所以只有在所有的祖先类装入器都找不到类之后,当前的类装入器才会涉及到。换句话说,使用委托模型。

ClassLoader 类

因为有不止一个类装入器,所以它们在根是引导类装入器的树中表示。每个类装入器都有一个对其父类装入器的引用。当一个类装入器被要求装入一个类时,它会在尝试装入项目本身之前咨询它的父类装入器。父节点依次咨询其父节点,依此类推。所以只有在所有的祖先类装入器都找不到类之后,当前的类装入器才会涉及到。换句话说,使用委托模型。

java.lang.ClassLoader是一个抽象类,可以被需要扩展 JVM 动态加载类的方式的应用程序子类化。java.lang.ClassLoader(及其子类)中的构造函数允许您在实例化新的类装入器时指定父类。如果没有显式地指定父类,那么虚拟机的系统类装入器将被指定为默认的父类。换句话说,ClassLoader 类使用委托模型来搜索类和资源。因此,ClassLoader 的每个实例都有一个关联的父类装入器,这样当请求查找类或资源时,任务在尝试查找类或资源本身之前就被委托给其父类装入器。ClassLoader 的 loadClass()方法在调用加载类时按顺序执行以下任务:

ClassLoader 类

java.lang.ClassLoader是一个抽象类,可以被需要扩展 JVM 动态加载类的方式的应用程序子类化。java.lang.ClassLoader(及其子类)中的构造函数允许您在实例化新的类装入器时指定父类。如果没有显式地指定父类,那么虚拟机的系统类装入器将被指定为默认的父类。换句话说,ClassLoader 类使用委托模型来搜索类和资源。因此,ClassLoader 的每个实例都有一个关联的父类装入器,这样当请求查找类或资源时,任务在尝试查找类或资源本身之前就被委托给其父类装入器。ClassLoader 的 loadClass()方法在调用加载类时按顺序执行以下任务:

如果类已经被加载,它将返回它。

如果类已经被加载,它将返回它。 否则,它将对新类的搜索委托给父类装入器。 否则,它将对新类的搜索委托给父类装入器。 如果父类装入器没有找到该类,则 loadClass()调用方法 findClass()来查找并装入该类。 如果父类装入器没有找到该类,则 loadClass()调用方法 findClass()来查找并装入该类。 如果父类装入器没有找到该类,则 finalClass()方法在当前类装入器中搜索该类。


如果父类装入器没有找到该类,则 finalClass()方法在当前类装入器中搜索该类。


原始文章中还有更多内容,它还向您展示了如何实现您自己的网络类加载器,从而回答了您为什么(以及如何)这样做的问题。参见 API 文件

原始文章中还有更多内容,该文章还向您展示了如何实现自己的网络类加载器,并回答了您关于为什么(以及如何)的问题。参见 API 文件

} } }

大多数 Java 开发人员将永远不需要显式地使用类装入器(除了装入资源以便在它们被绑定到 JAR 中时仍然可以工作) ,更不用说编写自己的类装入器了。

也许最透明的方法是以下列方式使用 管理员类的 延迟函数:

new Handler().postDelayed(this::function, 1000);

ClassLoader 在大型系统和服务器应用程序中用于执行以下操作:

    或者你可以在里面实现函数,例如:

    new Handler().postDelayed(() -> System.out.println("A second later"), 1000);
    
  • 模块化系统并在运行时加载、卸载和更新模块
  • 第一个参数是函数,第二个参数是以毫秒为单位的延迟时间。

  • 并行使用 API 库的不同版本(例如 XML 解析器)
  • 在第一个示例中,被调用函数的名称是“ function”
  • 隔离在同一 JVM 中运行的不同应用程序(确保它们不会相互干扰,例如通过静态变量)

用法:

 startMethodAfterNMilliseconds(new Runnable() {
@Override
public void run() {
// myMethod(); // Your method goes here.
}
}, 1000);

Bootstrap (原始) 这个类装入器不能重新装入。装入 JDK 内部类,java.* 包(通常装入 rt.jar 和 i18n.jar)。 外展

< a href = “ http://dev.mysql.com/doc/refman/5.1/en/date-and-time-function. html # function _ DATEDIFF”rel = “ noReferrer”> DATEDIFF 函数呢?

这个类装入器不能重新装入。从 JDK 扩展目录(通常是 JRE 的 lib/ext)装入 jar 文件。

引用说明书的页面:

系统

DATEDIFF ()返回 expr1-expr2 此类装入器不可重新装入。从系统类路径装入类。

Http://www.sbalasani.com/2015/01/java-class-loaders.html

注意,如果想在两个日期之间计算 整整24小时,datediff 可能会返回错误的值。

如文件所述:

计算中只使用值的日期部分。

结果就是

select datediff('2016-04-14 11:59:00', '2016-04-13 12:00:00')

返回1而不是期望的0。

解决方案是使用 select timestampdiff(DAY, '2016-04-13 11:00:01', '2016-04-14 11:00:00'); (注意与 datediff 相比,参数的顺序是相反的)。

一些例子:

  • 返回0
  • 报税表1
  • select timestampdiff(DAY, '2016-04-13 11:00:00', now()); 返回从2016-04-1311:00:00到现在24小时过去了多少天.

更多@: How-classloader-works-in-java. html

  • 第三个也是主要的类装入器是 AppClassLoader

    Commandlinefu 有两个有趣的命题:

    for k in $(git branch | perl -pe s/^..//); do echo -e $(git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | head -n 1)\\t$k; done | sort -r
    
    应用程序类装入器负责装入类

    或:

    for k in $(git branch | sed s/^..//); do echo -e $(git log --color=always -1 --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k --)\\t"$k";done | sort
    
    在 java.class.path 系统属性中提到的文件。

  • 还需要注意的是,可以覆盖默认的 ClassLoader 实现,使您能够以有用和有趣的方式定制 JVM,从而允许您完全重新定义如何将类文件引入系统。

    enter image description here

    使用 git branch -r,您可以类似地显示远程分支:

    for k in $(git branch -r | perl -pe 's/^..(.*?)( ->.*)?$/\1/'); do echo -e $(git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | head -n 1)\\t$k; done | sort -r
    

    点击这里了解更多关于 Java 类装入器的信息。

    ? $/1/’”) ; do echo-e $(git show —— pretty = format: “% Cgreen% ci% Cblue% cr% Creset”$k —— | head-n 1) t $k; done | sort-r’;

    Michael Forrest 提到了 在评论中,zsh 需要对 sed表达式进行转义:

    for k in git branch | perl -pe s\/\^\.\.\/\/; do echo -e git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | head -n 1\\t$k; done | sort -r
    

    多行:

    alias gbage='for k in $(git branch -r | \
    perl -pe '\''s/^..(.*?)( ->.*)?$/\1/'\''); \
    do echo -e $(git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | \
    head -n 1)\\t$k; done | sort -r'
    

    连续性补充了 在评论中:

    如果您想添加它,则需要使用以下转义符。

    alias gbage='for k in $(git branch -r | perl -pe '\''s/^..(.*?)( ->.*)?$/\1/'\''); do echo -e $(git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | head -n 1)\\t$k; done | sort -r'
    

    多行:

    alias gbage='for k in $(git branch -r | \
    perl -pe '\''s/^..(.*?)( ->.*)?$/\1/'\''); \
    do echo -e $(git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | \
    head -n 1)\\t$k; done | sort -r'
    

    注: 基于 git for-each-ref refs/headsN8tr回答更干净。

    注: 基于 git for-each-ref refs/headsN8tr回答更干净。
    另见“ git branch --list的唯一名称选项?

    另见“ git branch --list的唯一名称选项?

    更一般地说,三人行提醒我们 在评论中:

      更一般地说,三人行提醒我们 在评论中:

      • 更喜欢现代的 $(command substitution)语法而不是过时的 backtick 语法。
    • 更喜欢现代的 $(command substitution)语法而不是过时的 backtick 语法。

    (我在2014年用“ 在 shell 编程中,ABC0和 `command`的区别是什么?”说明了这一点)

    此外,您还可以为您的特定情况创建自己的 ClassLoader 类。例如,从某个存储库加载类,使用版本控制、卸载和安全性

    使用 getClassLoader()检查究竟是谁加载了您的类

    SomeClass.class.getClassLoader()
    

    Olivier Croquette为基础,我喜欢使用相对日期并缩短分支名称,如下所示:

    git for-each-ref --sort='-authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/heads
    

    查找类流(委托模型)

    child classloader find in cache
    if not
    parent classloader find in cache
    if not
    parent classloader try to load
    if not
    child classloader try to load
    

    它给你输出:

    21 minutes ago  nathan/a_recent_branch
    6 hours ago        master
    27 hours ago    nathan/some_other_branch
    29 hours ago    branch_c
    6 days ago      branch_d
    

    [ ClassNotFoundException vs NoClassDefFoundError 和隐式 vs 显式类加载]

    我建议创建一个 Bash 文件,用于添加所有您喜欢的别名,然后将该脚本分享给您的团队。这里有个例子可以补充这一点:

    #!/bin/sh
    
    
    git config --global alias.branches "!echo ' ------------------------------------------------------------' && git for-each-ref --sort='-authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/heads && echo ' ------------------------------------------------------------'"
    

    [ iOS 动态链接器]