Java中可替代固定大小数组的方法?

3

[背景:刚接触Java不到4个月,是C++老手。]

我正在开发一个需要在多处使用固定大小的数组(“固定字符串”)的库。我尝试使用依赖注入(详见q.v.)来解决这个问题,因此我希望得到以下形式的内容:

class Foo 
{
    private Bar injectedBar;
    private char[] injectedFixedString;

    Foo(Bar injectedBar, /* what can go here? */ char[5] injectedFixedString);
    { /* initializing code goes here /* }
}

需要简单明了——这将进入一个自动生成的通讯协议。我对协议和数据库没有任何控制权;在最终代码中,我将有数百甚至数千个这样的实例。所以,考虑到所有这些:

我的唯一选择是使用C++吗?

char injectedFixedString[5];

创建一个自定义的类?类似于以下内容:
class FixedBarString {
    /* could also set this in the constructor, but this complicates code generation a tad */
    public static integer STRING_SIZE = 5; /* string size */
    char[] fixedString = new char[STRING_SIZE];

    FixedBarString(char[] string) throws RuntimeException {
      /* check the string here; throw an exception if it's the wrong size.
         I don't like constructors that throw however. */
    }

    public void setString(char[] string) throws RuntimeException {
      /* check the string here */
    }

    public char[] getString() {
      /* this isn't actually safe, aka immutable, without returning clone */
    }

    public char[] createBlankString() {
      return new char[STRING_SIZE];
    }
}

感谢您。如果这段代码太多了,我很抱歉。

1
写了一个答案,然后意识到我实际上不知道你在这里想做什么。如果你传递一个包含6个字符的字符串,那么Foo(Bar injectedBar,/这里可以放什么?/char[5] injectedFixedString);会发生什么?如果我知道C++如何处理它,我可能能够更好地帮助你。 - Endophage
OP正在寻找C++固定大小数组的替代方法,例如在C++中,以下方法声明是有效的:myMethod(char myarray[5]) - dogbane
@dogbane:那个声明是做什么用的? - Michael Borgwardt
如果你用一个 char array[3] 调用这个方法,编译器会提示你这是不合法的。当你使用静态大小的数组时,编译器能够检测类型不匹配的情况。 - dogbane
这是为其他程序员设计的一个库,用于使用位打包协议。在这种情况下,我希望清楚地向调用者显示给定字段是例如“3个字符”,同时防止任何“不正确”的调用首先发生。 - John Price
可能需要更多的细节。为了构造类型为“Foo”的消息,我希望调用者创建子消息“Bar”和长度为5的字符字符串。 “Foo”的构造函数应该尽可能“明显且免疫错误”,以避免调用程序员的“错误标记”。(另见上面dogbane的评论)。 - John Price
4个回答

2

我不完全确定您想要实现什么。是防止在使用不同大小的数组调用构造函数吗?在编译时?为什么在运行时进行检查和抛出异常不是可接受的解决方案?

如果您的依赖注入框架支持新的bean validation标准,那么这将在注入期间对其进行检查:

Foo(Bar injectedBar, @Size(min=5,max=5) char[] injectedFixedString)

目标平台是Android(1.6,但我们将升级到2.2),而我对Android的了解甚至比Java还少。如果支持的话,那就可以了。 - John Price

2

实际上,如果您想要一个静态保证长度的字符串,除非您准备为每个长度创建一个新类(如FixedBarString4、FixedBarString5等),否则没有办法满足您的需求。(虽然可以创建一个使用泛型编码长度的字符单向链表类,但我怀疑您不会在实际场景中使用它。)


1
谢谢,看起来这是我不得不走的路。我的简短谷歌搜索没有找到任何有关Bean Validation和Android的有希望的结果。 - John Price

1

在 Java 程序中,你不能直接使用 java.lang.String ,只有在必要的时候才将其转换为数组。可以使用 toCharArray() 方法,并在此之前限制字符串的长度(例如使用 commons-lang 库中的 StringUtils.right(str, 5) 方法)。

或者,当传递给方法的字符串长度超过 5 时,可以抛出一个 IllegalArgumentException 异常。


在这种情况下,我需要调用程序员知道库需要恰好"N"个字符;对子集进行操作会在这个特定协议中引起太多问题。例如,这可能是一个唯一的ID(我不太担心注释字段)。例如——如果字段是一个6位数字ID,那么"12345678"真的是ID "123456"、"234567"还是"345678"?调用者如何调试?缺少足够的字符几乎可以保证在许多情况下调用者将无法获得他/她想要的结果。在ID示例中,"123"将无法匹配任何六位数ID。 - John Price

0

你可以拥有

Foo(Bar injectedBar, char[] injectedFixedString)

并使用以下方式调用

new Foo(injectedBar, new char[5])

或者

Foo(Bar injectedBar, fixedStringLength)
new Foo(injectedBar, 5)

值得注意的是,char类型占用2个字节而不是1个字节。你的协议是否假定字符为16位或8位?

@peter-lawrey 是的,但在构造函数中,您仍然需要检查传入的数组长度是否为5。您不能像C ++一样声明 Foo(Bar injectedBar,char injectedFixedString [5]) - dogbane
我需要的实际值是7位ASCII,但根据网络(购物需谨慎),Unicode的前128个值(0-127)是ASCII集。 我计划将这些值从16位掩码减少到7位。 - John Price
@John,你应该使用一个8位的byte[]。 - Peter Lawrey
是的,谢谢。看起来我可以使用内置的java.io方法将ASCII的byte[]转换为UTF-8<->Unicode,这是一个问题(之前的谷歌搜索不确定)。由于这是一个位压缩协议(它只会使用7位),所以这应该没有关系;但这是Android,所以空间非常重要。 - John Price

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接