Get a load of that name! (很不错的文章!)

Harness-of-Harness:多日自主软件开发中的持续改进机制 大语言模型驱动的自动化编程正在逐步改变开发者的工作方式,但当前大多数AI编程助手的表现仍集中在单点任务上,难以支撑跨越多日的完整项目迭代。当开发周期拉长,上下文不一致、状态丢失、方向偏移等问题会迅速累积,纯靠模型能力无法维持工程纪律。持续集成与自动化测试的成熟实践,为构建长周期自主开发系统提供了坚实基础。在这一背景下,Harness-of-Harness概念应运而生,它通过外层约束、逐日验证、结构化反馈与跨天记忆,将Agent的执行从自由生成转变成受控的工程过程。这种设计不仅适用于前沿研究,也能为普通团队优 阅读详情
 

Get a load of that name!

Subtle differences in various ways you can dynamically load a class

 

By Vladimir Roubtsov


Printer-friendly version Printer-friendly version | Send this article to a friend Mail this to a friend


 

March 14, 2003

Q What is the difference between Class.forName() and ClassLoader.loadClass()?

A Both methods try to dynamically locate and load a java.lang.Class object corresponding to a given class name. However, their behavior differs regarding which java.lang.ClassLoader they use for class loading and whether or not the resulting Class object is initialized.

The most common form of Class.forName(), the one that takes a single String parameter, always uses the caller's classloader. This is the classloader that loads the code executing the forName() method. By comparison, ClassLoader.loadClass() is an instance method and requires you to select a particular classloader, which may or may not be the loader that loads that calling code. If picking a specific loader to load the class is important to your design, you should use ClassLoader.loadClass() or the three-parameter version of forName() added in Java 2 Platform, Standard Edition (J2SE): Class.forName(String, boolean, ClassLoader).

Additionally, Class.forName()'s common form initializes the loaded class. The visible effect of this is the execution of the class's static initializers as well as byte code corresponding to initialization expressions of all static fields (this process occurs recursively for all the class's superclasses). This differs from ClassLoader.loadClass() behavior, which delays initialization until the class is used for the first time.

You can take advantage of the above behavioral differences. For example, if you are about to load a class you know has a very costly static initializer, you may choose to go ahead and load it to ensure it is found in the classpath but delay its initialization until the first time you need to make use of a field or method from this particular class.

The three-parameter method Class.forName(String, boolean, ClassLoader) is the most general of them all. You can delay initialization by setting the second parameter to false and pick a given classloader using the third parameter. I recommend always using this method for maximum flexibility.

Class initialization errors are tricky
Just because you successfully load a class does not mean there won't be any more problems. Recollect that static initialization code can throw an exception, and it will get wrapped in an instance of java.lang.ExceptionInInitializerError, at which point, the class becomes unusable. Thus, if it is important to process all such errors at a known point in code, you should use a Class.forName() version that performs initialization.

Furthermore, if you handle ExceptionInInitializerError and take measures so that the initialization can be retried, it will likely not work. This code demonstrates what happens:

public class Main
{
    public static void main (String [] args) throws Exception
    {
        for (int repeat = 0; repeat < 3; ++ repeat)
        {
            try
            {
                // "Real" name for X is outer class name+$+nested class name:
                Class.forName ("Main$X");
            }
            catch (Throwable t)
            {
                System.out.println ("load attempt #" + repeat + ":");
                t.printStackTrace (System.out);
            }
        }
    }

    private static class X
    {
        static
        {
            if (++ s_count == 1)
                throw new RuntimeException ("failing static initializer...");
        }
        
    } // End of nested class

    private static int s_count;

} // End of class

This code attempts to load the nested class X three times. Even though X's static initializer fails only on the first attempt, all of them fail:

>java Main
load attempt #0:
java.lang.ExceptionInInitializerError
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:140)
        at Main.main(Main.java:17)
Caused by: java.lang.RuntimeException: failing static initializer...
        at Main$X.<clinit>(Main.java:40)
        ... 3 more
load attempt #1:
java.lang.NoClassDefFoundError
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:140)
        at Main.main(Main.java:17)
load attempt #2:
java.lang.NoClassDefFoundError
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:140)
        at Main.main(Main.java:17)

It is slightly surprising that the errors on subsequent load attempts are instances of java.lang.NoClassDefFoundError. What happens here is that the JVM has already noted the fact that X has been loaded (before the initialization is attempted), and the class cannot be unloaded until the current classloader is garbage collected. So, on subsequent calls to Class.forName(), the JVM does not attempt initialization again but, rather misleadingly, throws an instance of NoClassDefFoundError.

The proper way to reload such a class is to discard the original classloader instance and create a new one. Of course, this can be done only if you had anticipated that and used the proper three-parameter form of forName().

The hidden Class.forName()
I am sure you have used Java's X.class syntax to obtain a Class object for a class whose name is known at compile time. Less well known is how this is implemented at the byte-code level. The details are different across compilers, but all of them generate code that uses the one-parameter form of Class.forName() behind the scenes. For example, javac from J2SE 1.4.1 translates Class cls = X.class; into the following equivalent form:

    ...
        // This is how "Class cls = X.class" is transformed:
        if (class$Main$X == null)
        {
            class$Main$X = class$ ("Main$X");
        }
        Class cls = class$Main$X;

    ...

    static Class class$ (String s)
    {
        try
        {
            return Class.forName (s);
        }
        catch (ClassNotFoundException e)
        {
            throw new NoClassDefFoundError (e.getMessage());
        }
    }

    static Class class$Main$X; // A synthetic field created by the compiler

Of course, everything mentioned above about Class.forName()'s short form always initializing the class in question applies to X.class syntactic form as well. The details are different when such syntax is used to get Class objects for primitive and array types, and I leave that as an exercise for curious readers.

Fun with Sun's javac
In the previous example, you saw that the result of loading the class was cached in a special package-private static field artificially created by the compiler, and a synthetic helper method executed Class.forName(). The reason this is convoluted may be because the syntax used was unavailable in early Java versions, so the feature was added on top of the Java 1.0 byte-code instruction set.

Armed with this insight, you can have a bit of fun at the compiler's expense. Compile this tongue-in-cheek code snippet using javac from J2SE 1.3.1:

public class Main
{
    public static void main (String [] args) throws Exception
    {
        System.out.println ("String class: " + String.class);
        class$java$lang$String = int.class;
        System.out.println ("String class: " + String.class);
    }
    
    static Class class$java$lang$String;

} // End of class

If you run it, you will get the following, which is ridiculous at best:

>java Main
String class: class java.lang.String
String class: int

At least the compiler in J2SE 1.4.1 will reject the code above. But you can still fool it by setting the field reflectively:

    public static void main (String [] args) throws Exception
    {
        System.out.println ("String class: " + String.class);
        Main.class.getDeclaredField ("class$java$lang$String").set (null, int.class);
        System.out.println ("String class: " + String.class);
    }

So, next time you code the familiar Class.forName() incantation, you should know what it entails and what alternatives exist.


Printer-friendly version Printer-friendly version | Send this article to a friend Mail this to a friend

About the author
Vladimir Roubtsov has programmed in a variety of languages for more than 13 years, including Java since 1995. Currently, he develops enterprise software as a senior developer for Trilogy in Austin, Texas.

 

基于向量嵌入的博客文章自动打标签系统:从原理到工程实践 在信息检索和内容管理领域,文本的语义理解是关键挑战。传统方法如词袋模型或关键词匹配,难以捕捉词汇间的语义关联,容易产生无关或重复的标签,即“幻觉”标签。向量嵌入技术通过深度学习模型将文本转换为高维空间中的稠密向量,这些向量能编码语义和上下文信息,使得语义相似的文本在向量空间中距离更近。这项技术的核心价值在于实现了基于内容的动态、精准关联,而非依赖预设的固定分类体系。在工程实践中,通过计算文章向量与候选标签向量之间的相似度(如余弦相似度),可以自动为内容分配合适的标签。这广泛应用于博客平台、内容管理系统和知识 阅读详情

相关推荐

手把手教你用.NET Reactor 7.3.0保护跨平台.NET应用(含macOS/Rider配置)

本文详细介绍了如何使用.NET Reactor 7.3.0为跨平台.NET应用提供代码保护。文章重点涵盖了在macOS环境下的GUI工具安装、与JetBrains Rider的深度集成配置,并针对Avalonia UI框架提供了专项保护策略和避坑指南,帮助开发者有效防止代码被反编译和破解。

coffee的博客 594

java.lang.NoClassDefFoundError 使用MultiDex 后,运行时发现有些crash或者有些类无法调用 报NoClassDefFound error

首先正确使用 google的multipartdex 修改Gradle,导入’com.android.support:multidex:1.0.0’,打开multiDexEnabled; android { compileSdkVersion 21 buildToolsVersion "21.1.0" defaultConfig { ... mi

yabin的专栏 6855

Verilog实现SPI通信协议驱动设计

线性序列机实现SPI协议

H19981118的博客 6085

错误:java.lang.NoClassDefFoundError: Failed resolution of: Lokio/Buffer;

错误描述: java.lang.NoClassDefFoundError: Failed resolution of: Lokio/Buffer;     at okhttp3.ResponseBody.create(ResponseBody.java:210)     at okhttp3.internal.Util.&lt;clinit&gt;(Util.java:62)     at ok...

牛八少爷的专栏 9926

保姆级教程:在SIwave 2024 R2中搞定TDR仿真,手把手教你分析USB 3.0差分线阻抗

本文提供了一份详细的SIwave 2024 R2 TDR仿真教程,重点讲解如何分析USB 3.0差分线阻抗。从项目准备、参数配置到结果分析,逐步指导工程师完成完整的仿真流程,并分享实战经验和高级技巧,帮助提升信号完整性分析能力。

weixin_33670786的博客 498

【sap2000】部分模型通过.s2k文件合并模型generating a global model through partial models by .s2k text file

现在需要通过选项File → Import → SAP2000 .s2k Text File → Add to existing model(如果使用其中一个部分模型作为基础)或New model(如果使用新文件)添加部分模型,并使用以下导入选项。模型A(阶段1/5) Model A (Phase 1/5)模型B(阶段2/5) Model B (Phase 2/5)模型C(阶段3/5) Model C (Phase 3/5)模型E(阶段5/5) Model E (Phase 5/5)

hmywillstronger的博客 1751

怎么解决java.lang.NoClassDefFoundError错误

前言在日常Java开发中,我们经常碰到java.lang.NoClassDefFoundError这样的错误,需要花费很多时间去找错误的原因,具体是哪个类不见了?类明明还在,为什么找不到?而且我们很容易把java.lang.NoClassDefFoundError和java.lang.ClassNotfoundException这两个错误搞混,事实上这两个错误是完全不同的。我们往往花费时间去不断尝试

jamesjxin的专栏 123万+

基于C#的ASP.NET开发的党史学习网站课设

开展党史学习教育,就是要以史为镜、以史明志,把苦难辉煌的过去、日新月异的现在、光明宏大的未来贯通起来,在鉴往知来中砥砺前行,在乱云飞渡中把准航向,在凝心聚力中团结奋斗,共同创造新的历史伟业。登陆按钮与数据库进行连接,逻辑实现是如图3.1.3所示,自己定义一个SQL查询语句,将账号、密码放入SQL查询语句中,用sqlDataReader.HasRows语句进行逐一比较,找出结果,将用户名存入session并调用cookies,如果结果存在就关闭数据库,进行数据跳转,并弹出登陆成功的提示框,并关闭数据库。

m0_62408555的博客 974

【转】Get a load of that name! (很不错的文章!)

Get a load of that name! Subtle differences in various ways you can dynamically load a class By Vladimir Roubtsov Printer-friendly version | Mail this to a friend ...

weixin_30904593的博客 186

097、Zephyr RTOS驱动开发实战:传感器驱动(陀螺仪)

I2C速率别设太高:LSM6DSO支持最高400kHz,但实际布线有寄生电容时,400kHz容易出错。工业产品我统一用100kHz,稳定压倒一切。FIFO水印值要计算:假设ODR=6.66kHz,每150us产生一组数据,如果水印设32组,则每4.8ms触发一次中断。这个间隔要大于I2C读取耗时(实测约200us),否则中断堆积。电源纹波敏感:陀螺仪对电源噪声敏感,特别是3.3V供电时。我遇到过因为DC-DC纹波太大,陀螺仪输出噪声从0.1dps飙升到2dps。

m0_50546716的博客 118

WPF中使用TreeView封装组合控件TreeView+DataGrid

wpf的功能非常强大,很多控件都是原生的,但是要使用TreeView+DataGrid的组合,就需要我们自己去封装实现。功能如上图所示, 目前基本上把常用的样式都实现了,购买源码后,可以自行修改样式。本文源码效果如下,(搞了好几天,的确有难度,所以源码也收费,便宜,赚点辛苦费)第一种:技术的选择是TreeView(也就是本文的演示)。这2个图都是第三方控件自带的,并且都是收费使用。首先说明一下,实现上面的效果,有3种方法。本文演示的是使用TreeView的实现。第二种:技术的选择是DataGrid。

故里2130 1650

jQuery+Ajax+全解析

jQuery Ajax 全解析 <!-- .ajax div {border-bottom:red 1px solid; border-left:red 1px solid; border-top:red 1px solid; border-right:r

gisergising 861

手把手教你用ESP32-S3打造智能聊天机器人-立创实战派

本文将详细介绍如何利用立创ESP32-S3开发板,烧录小智AI程序,快速实现一个功能强大的聊天机器人。

举世誉之而不加劝,举世非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。 9919

jQuery.ajax 使用点滴

以下是转载 jQuery Ajax 全解析 本文地址: jQuery Ajax 全解析 本文作者:QLeelulu 转载请标明出处! jQuery确实是一个挺好的轻量级的JS框架,能帮助我们快速的开发JS应用,并在一定程度上改变了我们写JavaScript代码的习惯。 废话少说,直接进入正题,我们先来看一些简单的方法,这些方法都是对jQuery.

未来软件 663

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

jQuery Ajax 全解析

本文地址: jQuery Ajax 全解析 本文作者:QLeelulu 转载请标明出处! jQuery确实是一个挺好的轻量级的JS框架,能帮助我们快速的开发JS应用,并在一定程度上改变了我们写JavaScript代码的习惯。 废话少说,直接进入正题,我们先来看一些简单的方法,这些方法都是对jQuery.ajax()进行封装以方便我们使用的方法,当然,如果要处理复杂的逻辑,还是需要用到j

snowalkmount的专栏 442

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

转载 jquery ajax 全解析

原文:http://www.cnblogs.com/qleelulu/archive/2008/04/21/1163021.html       昨天从ajax转到jquery.ajax方法,有一种比葫芦画瓢的感觉,总之自己没有学通,今天晚上搜到一篇不错的文章,防止日后自己在栽在 jquery.ajax上。   jQuery确实是一个挺好的轻量级的JS框架,能帮助我们快速的开发JS应用,并...

whaohaoxuexi02的专栏 202

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

jQuery Ajax 实例 全解析

ps:还是比较详细的,load,get,post,ajax等请求方式之间的区别使用。虽然没有太多深入,但作为资料参考还是不错的。感谢文章的作者。 jQuery Ajax 实例 全解析 jQuery确实是一个挺好的轻量级的JS框架,能帮助我们快速的开发JS应用,并在一定程度上改变了我们写JavaScript代码的习惯。 废话少说,直接进入正题,我们先来看一些简单的方法,这些

TechBirds在路上 1236

Keras预训练模型加载全指南:从权重下载到微调避坑

在深度学习工程中,预训练模型加载是迁移学习落地的第一步,也是许多初学者最容易卡壳的环节。理解权重存储格式、加载API差异以及底层序列化机制,是高效复用大规模数据集训练成果的关键技术价值。通过内置应用模块或本地模型文件,开发者可以在图像分类、目标检测等场景中快速构建高精度模型,避免从零训练带来的数据与算力瓶颈。然而,下载超时、Unknown layer报错、Shape不匹配等问题频繁出现,往往源于对缓存路径、自定义层注册及训练状态切换的细节疏忽。掌握加载后的冻结与微调配置,能帮助模型适配小样本任务,同时保持预

weixin_33901926的博客 341

LangChain--05--Tools

使用@tool装饰器(推荐。

时光里的博客 50
上一篇: Find a way out of the ClassLoader maze (2)
下一篇: 类加载器的收获
DeepNightTwo
博客等级 码龄21年 3粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值