1

菜鸟java问题。

对于我的项目,我在 XML 文件中定义了一个类模型,然后我将其转换为模型。例如:

<model>
    <class name="abc"><field>one</field><field>two</field></class>
    <class name="xyz"><field>f1</field><field>f2/field></class>
</model>

这被转化为:

public class abc {
    String _one;
    String _two;
    public String get_one() {
        return _one;
    }
... and so on you get an idea

显然,将每个类转换为自己的 .java 文件会很麻烦。将它们堆积在一个 .java 文件中会更易于管理。但是,java 有这个要求,每个类都必须定义在自己的文件中,并且文件名必须与类名匹配。否则编译器会报错:The public type XYZ must be defined in its own file

很可能可以这样定义:

public class ModelContainer {

    public class abc {
        ...
    }
    public class xyz {
        ...
    }
}

还有其他方法吗?理想情况下,我正在寻找编译器开关或类似的东西,这将禁用将每个类放在自己的文件中的要求。如果这有什么不同,我正在使用 Eclipse

4

4 回答 4

1

如果您可以使用内部类,那么是的,这将起作用,但是每次要实例化内部类时都必须获取外部类的实例:

public class ModelContainer {
    public class abc {
        ...
    }
    public class xyz {
        ...
    }
}

您也可以将嵌套类声明为静态,因此不必先实例化外部类:

public class ModelContainer {
    public static class abc {
        ...
    }
    public static class xyz {
        ...
    }
}

查看这篇文章了解更多详细信息。

于 2013-11-01T16:43:51.653 回答
1

有趣的是,将每个顶级类放在自己的文件中实际上并不是语言要求.java

当且仅当包存储在文件系统中(第 7.2 节)时,如果在由类型名称组成的名称下的文件中未找到类型,则主机系统可能会选择强制执行它是编译时错误的限制如果以下任一情况为真,则加上扩展名(例如.java.jav):

  • 该类型由声明该类型的包的其他编译单元中的代码引用。
  • 该类型已声明public(因此可以从其他包中的代码访问)。

也就是说,由于编译器可能会强制执行这样的要求,因此所有可移植代码都应符合惯例。

关于您的具体情况,您应该将每个文件的顶级类规则视为语言要求。通常的方法实际上是.java为每个类生成一个单独的文件(使用嵌套类有很多烦人的方面,甚至是静态类),但是如果你有更好的理由,你可以通过使用嵌套类来解决这个问题关闭和打开文件。

于 2013-11-01T16:52:13.263 回答
1

另一种但稍微复杂一点的方法是完全跳过创建 Java 源代码。您可以使用 Javassist 或 ASM 等字节码库直接创建类文件。本质上,您会将XML 声明编译为可执行代码。

如果您正在创建如图所示的简单值对象,这将非常容易。

您似乎在生成大量文件时遇到问题,因此您可以将类文件直接写入 JAR 文件(使用 ZIP I/O 类)并将合成类生成为单个库文件。

(您可能希望将这些类标记为合成类,尽管 XML 声明可以被视为源代码,这意味着它们在技术上不是合成的。)

于 2013-11-01T17:00:19.090 回答
0

您想要的编译器开关不存在。确保每个类都在一个正确命名的文件中——并且在目录层次结构中的正确位置,假设你在包中组织你的类——总是由 Java 编译器强制执行的。大多数 Java 开发人员不会梦想将其关闭,因为这种组织源代码的方式被认为是一种很好的做法。(因此,Java 开发人员在尝试使用不强制执行此限制的 C# 等语言导航大型、不守规矩的项目时会做些小噩梦。)

唯一不需要遵守此约束的类是匿名类或内部类,但您的应用程序不应主要由这些类组成。

于 2013-11-01T16:49:40.010 回答