栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Java中初始化字符串的大小

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java中初始化字符串的大小

字符串文字的长度(即

"..."
)受类文件格式的
CONSTANT_Utf8_info
结构限制,该结构由该
CONSTANT_String_info
结构引用。

CONSTANT_Utf8_info {    u1 tag;    u2 length;    u1 bytes[length];}

此处的限制因素是

length
属性,该属性只有2个字节大,即最大值为65535。该数字对应于字符串的已修改UTF-8表示形式中的字节数(实际上几乎是CESU-8,但0字符也以两字节形式表示)。

因此,一个纯ASCII字符串文字最多可以包含65535个字符,而由范围在U + 0800 … U +
FFFF范围内的字符组成的字符串仅占其中的三分之一。并且在UTF-8中编码为代理对的对(即U + 10000到U + 10FFFF)每个占用6个字节。

(因为标识符使用相同的结构,所以标识符(即类,方法和变量名以及它们的类型描述符)具有相同的限制。)

Java语言规范未提及字符串文字的任何限制:

字符串文字包含零个或多个用双引号引起来的字符。

因此,原则上,编译器可以将较长的字符串文字拆分为多个

CONSTANT_String_info
结构,并在运行时通过串联(和
.intern()
-ing结果)对其进行重构。我不知道是否有任何编译器实际上正在执行此操作。


它表明该问题与字符串文字无关,而与数组初始化程序有关。

当将一个对象传递给

BMethod.invoke
(和BConstructor.newInstance相似)时,它可以是BObject(即围绕现有对象的包装,然后将传递包装的对象),String(照原样传递),或者还要别的吗。在最后一种情况下,对象将被转换为字符串(by
toString()
),然后将该字符串解释为Java表达式。

为此,BlueJ将把此表达式包装在类/方法中并编译此方法。在该方法中,将数组初始化程序简单地转换为一长串的数组分配…,这最终使该方法比Java方法的最大字节码大小长:

pre_length项的值必须小于65536。

这就是为什么它会中断较长数组的原因。


因此,要传递更大的数组,我们必须找到其他方法将它们传递给BMethod.invoke。BlueJ扩展API无法创建或访问包装在BObject中的数组。

我们在聊天中发现的一个想法是:

  1. 在项目内部(或在新项目中,如果他们可以互操作)创建一个新类,如下所示:
    public class IntArrayBuilder {private ArrayList<Integer> list;public void addElement(int el) {    list.add(el);}public int[] makeArray() {    int[] array = new int[list.size()];    for(int i = 0; i < array.length; i++) {       array[i] = list.get(i);    }    return array;}

    }

(这是为了创建一个

int[]
-如果您还需要其他类型的数组,也可以使其更通用。此外,可以通过使用内部
int[]
存储来提高效率,随着内部存储的增长而偶尔地扩大它,然后int
makeArray进行最终的arraycopy。这是一个草图,因此这是最简单的实现。)

  1. 在我们的扩展中,创建一个此类的对象,然后通过调用其
    .addElement
    方法向该对象添加元素。
    BObject arrayToBArray(int[] a) {BClass builderClass = package.getClass("IntArrayBuilder");BObject builder = builderClass.getConstructor(new Class<?>[0]).newInstance(new Object[0]);BMethod addMethod = builderClass.getMethod("addElement", new Class<?>[]{int.class});for(int e : a) {    addMethod.invoke(builder, new Object[]{ e });}BMethod makeMethod = builderClass.getMethod("addElement", new Class<?>[0]);BObject bArray = (BObject)makeMethod.invoke(builder, new Object[0]);return bArray;

    }

(为了提高效率,实际上对于每个数组转换,BClass / BMethod对象实际上只能被检索一次并被缓存,而不是一次。)
如果您通过某种算法生成数组内容,则可以在此处进行此生成,而不必先创建另一个包装对象。

  1. 在我们的扩展中,通过传递包装的数组,调用我们实际想用long数组调用的方法:
    Object result = method.invoke(obj, new Object[] { bArray });


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/486493.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号