gpt4 book ai didi

java - 关于文件标记化、对象值设置和标记位置枚举的 API 设计

转载 作者:行者123 更新时间:2023-11-30 04:37:10 26 4
gpt4 key购买 nike

在我的 Android 应用程序中,我需要从一组最初(现在仍然)与 Windows 应用程序一起部署的 .ini 文件中读取大量数据。该应用程序与特定硬件有关,.ini 文件的基本目的是描述有关硬件设备的编程常量、实时数据和 UI 元素。

为了继续讨论我希望获得帮助的特定 Java 设计问题,这里有一个示例,说明 .ini 文件中的典型数据行是如何构建的。通常我们有一个参数名称,后跟各种字符串或数字数据列:

example = example,  "example",  "C",  0,   255,  -1,    -1,  256,  256 

然后,我解析和标记化的每一行数据都在应用程序中表示为一个对象。为了从 .ini 文件数据的每一行创建每个对象,我目前正在使用 Builder/Fluent 界面。因此,上面的行将导致一个对象被创建如下:

someObject.setName( t.s(2) ).setUnits( t.s(3) ).setLowerUpper( t.f(4), t.f(5) ) ...

t 是我用来解析 .ini 文件的 tokenizer 类实例,它的方法 s(int)f(int) 是获取给定列号的整数或 float 的 getter。

这有点困惑,因为我的基本 .ini 文件处理类根据标记器返回的数据执行对象创建,必须在行列的所有位置包含魔数(Magic Number)。我还必须注意适本地使用 s()f()(尽管如果我使用错误的,编译器当然会报告错误,基于我的对象 setter 所需的类型)。

我真正想做的是有另一个类,我可以称之为 IniFileDefinitions。理想情况下,该类将包含行号及其关联类型的枚举定义。因此,使用此类,上面的对象创建可能看起来类似于此(显然是伪代码):

someObject.setName( t.get(INI_NAME) ).setUnits( t.get(INI_UNITS) ).setLowerUpper( t.get(INI_LOWER), t.get(INI_UPPER) );

我有点卡住的地方是如何定义一个枚举值,我可以将它传递给我的分词器,并让分词器不仅使用该枚举来确定列号,而且还改变返回的类型(整数、字符串、 float 等)基于该枚举。

我意识到 Java 枚举非常强大,我可以让每个枚举有两个字段,其中第一个字段给出行号,第二个字段描述类型,例如:

public enum someIniEnumDefs{
INI_NAME( 2, INI_TYPE_STRING )
...

我突然想到,使这项工作起作用的一种方法是在我的分词器中有一个 getter 方法,它可以根据枚举说它应该是什么类型来改变它返回的类型,但显然这在 Java 中是不可能的.据我所知,我将不得不返回一个包含所有类型(字符串、整数、...)之一的自定义对象,或者只是简单地返回对象(呃)。我不是特别喜欢这两种解决方案。

我的一个想法是分词器可以有多个(重载的)值 get() 方法,每个方法返回不同的原始类型。将调用哪个特定的 get() 方法可能取决于我在枚举定义中的“类型”字段。我认为我无法做到这一点。我想到的唯一方法是将我的枚举分成几个代表不同类型的组,然后我的 tokenizer get 方法将像这样重载:

int get(SomeIniEnumDefs_Ints){ ... return someInt }
String get(SomeIniEnumDefs_Strings){ ... return someString }
...

考虑到我缺乏使用 Java 枚举的经验(我知道它比我在普通的旧 C 中使用的要强大得多!)我知道必须有一种巧妙的方法可以实现这一点。任何人都可以提供任何进一步的指导吗?

谢谢,

崔维

最佳答案

Java 枚举无法实现您尝试执行的操作。然而,它可以通过其他方式轻松实现:

public class IniParam<T> {

public static final IniParam<String> NAME = new IniParam<String>(2);

public static final IniParam<String> UNITS = new IniParam<String>(3);

public static final IniParam<Integer> LOWER = new IniParam<Integer>(4);

public static final IniParam<Integer> UPPER = new IniParam<Integer>(5);

private final int position;

private IniParam(int position) {
this.position = position;
}

public int getPosition() {
return position;
}
}

分词器可能看起来像:

public class Tokenizer {

public String get(IniParam<String> iniParam) {
int position = iniParam.getPosition();
//...
return "some string from .ini";
}

public int get(IniParam<Integer> iniParam) {
// ...
// return some integer from .ini
}
}

使用示例:

    Tokenizer t = new Tokenizer();
String name = t.get(IniParam.NAME);
int lower = t.get(IniParam.LOWER);
someObject.setName( t.get(IniParam.NAME) ).setUnits( t.get(IniParam.UNITS) ).setLowerUpper( t.get(IniParam.LOWER), t.get(IniParam.UPPER) );

更新

不幸的是,我上面提供的 Tokenizer 类无法使用 JDK 7/Eclipse 3.6+ 编译器进行编译(我现在无法自行检查,但修复了以下 OracleEclipse错误假设 get(...) 方法中的编译错误)。如果您遇到此问题,解决方法如下:

public class IniParam<T> {

public static final IniParam<String> NAME = new IniParam<String>(2, String.class);

public static final IniParam<String> UNITS = new IniParam<String>(3, String.class);

public static final IniParam<Integer> LOWER = new IniParam<Integer>(4, Integer.class);

public static final IniParam<Integer> UPPER = new IniParam<Integer>(5, Integer.class);

private final int position;

private final Class<? extends T> type;

private IniParam(int position, Class<? extends T> type) {
this.position = position;
this.type = type;
}

public int getPosition() {
return position;
}

public Class<? extends T> getType() {
return type;
}
}


public class Tokenizer {

public <T> T get(IniParam<T> iniParam) {
int position = iniParam.getPosition();
Class<? extends T> type = iniParam.getType();
if (type == String.class) {
//...
return type.cast("some string from .ini");
} else if (type == Integer.class) {
//...
// Integer result = ...;
return type.cast(result);
} else {
throw new IllegalArgumentException("Unexpected IniParam type: " + type);
}
}
}

关于java - 关于文件标记化、对象值设置和标记位置枚举的 API 设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6641723/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com