java方法名过长_java内部类的文件名太长了

我正在将某些语言的程序翻译成嵌套的java类.在某些时候,嵌套的程度变得如此之深以至于我得到:

编译Test.javaTest.java:5179:写错误:测试$2 … $1.class(文件名太长)

其中……是一个长串.

我正在使用ext3文件系统,因此我限制为256个字符长的文件名.此外,我想暂时继续使用这种翻译方法(对内部类),因为我更感兴趣的是测试执行闭包转换的语言,这将解决问题.是否有一种快速的方法来绕过这个? (使用不同的文件系统或告诉javac生成不同的文件名?)

解决方法:

底线是,是的,它是可行的.可以更改内部类的名称,因此它比javac指定的原始名称短.

案例和观点:

class A {

class B {

class C {}

}

A() {

new B().new C();

}

public static void main(String[] s){

new A();

}

}

在这里,我们有嵌套的内部类.编译时,我们得到以下文件:

A.class

A$B.class

A$B$C.class

这是一个快速实验:

>打开A.class文件,将引用更改为A $B $C并将其更改为ABCDE.

>将A $B $C.class重命名为ABCDE.class.

>打开ABCDE.class,并将引用更改为ABCDE.

>运行java A,查看它是否运行.

注意:A $B $C更改为ABCDE的原因是因为标识符长度的变化似乎会破坏类文件格式,并且会导致错误.技术说明将在本文末尾.

结果?有用.

原因是在类文件中.这是原始A.class的反汇编,只有相关部分:

Compiled from "A.java"

class A extends java.lang.Object

SourceFile: "A.java"

InnerClass:

#10= #3 of #7; //B=class A$B of class A

#22= #2 of #3; //C=class A$B$C of class A$B

// ... snip ... //

const #2 = class #21; // A$B$C

// ... snip ... //

const #21 = Asciz A$B$C;

// ... snip ...//

事实证明,内部类的名称只是常量池中的名称.

如果A.class的常量池中的A $B $C类的名称更改为ABCDE,并且更改了类文件中的A $B $C类的文件名和名称,那么Java虚拟机将很高兴执行新命名的内部类.

这是什么意思?

一个人不需要使用MyClass $1 $1 $1 … $1作为类名,但是其他任何东西都可以满足一个人的需要,因此,可以在更短的文件名中使用更多的组合.

怎么会有人去做呢?我将把这作为练习留给读者.

关于使用ABCDE作为新类名的说明

在这篇文章中,嵌套内部类的名称A $B $C被更改为ABCDE以保持类名的长度相同,以防止抛出ClassFormatError.其原因是常量池的CONSTANT_Utf8_info structure具有长度属性,该属性表示字符串的长度.我在文本编辑器中编辑类文件时无法更改长度.

为了缩短常量池中的字符串,我认为必须改变长度字段的值以反映字符串本身的长度.

更新

是的,可以编辑类文件的常量池以缩短内部类的名称.

我能够将ABCDE类更改为Z类.

这是A.class反汇编的一部分:

Compiled from "A.java"

class A extends java.lang.Object

SourceFile: "A.java"

InnerClass:

#10= #3 of #7; //B=class A$B of class A

#22= #2 of #3; //C=class Z of class A$B

// ... snip ...//

const #2 = class #21; // Z

// ... snip ...//

const #21 = Asciz Z;

// ... snip ...//

可以看出,内部类现在由Z引用,而不是A $B $C.

通过在A.class和A $B $C.class文件中查找字符串A $B $C并将其替换为Z,并将字符串之前的字符从值0x05更改为0x01来执行更改,表示字符串的长度现在是1而不是5.

通过这些更改,以及将文件重命名为Z.class,程序运行就好像什么也没发生过一样.

所以,是的,也可以缩短内部类的名称.

标签:java,filesystems

来源: https://codeday.me/bug/20190622/1260287.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值