【问题标题】:custom System class not compiling in command line自定义系统类未在命令行中编译
【发布时间】:2020-06-03 11:02:25
【问题描述】:

我有我自己的System 类,在同一个包中有一个测试类,测试方法在 System 类中声明。我还创建了一个带有 3 个参数的 System 构造函数。当我创建一个构造函数来测试我的 IDE 中的方法时,程序运行正常(我曾在需要使用 System.method 的地方使用 java.util.System)但 IDE 知道我在创建时指的是我自己的类构造函数。但是,当我尝试从命令行运行我的测试类时,它甚至不会编译:

error: constructor System in class System cannot be applied to given types;
        System sys = new System("String1", "String2", 20);
                           ^
  required: no arguments
  found:    String,String,int
  reason: actual and formal argument lists differ in length

我的猜测是,正在调用 java.util.System 构造函数(没有参数)而不是我的构造函数,这会导致整个程序崩溃。有谁知道如何修复它,为什么它只发生在命令行而不是 IDE 中?

【问题讨论】:

    标签: java package system


    【解决方案1】:

    您提到了java.util.System,但这不是平台系统所在的位置;它住在java.lang

    这是个问题。 Java 代码就像import java.lang.*; 位于每个文件的顶部一样,即使您不编写它也是如此。 java语言规范是这么说的。所以现在你陷入了一个有趣的困境:

    假设在同一个包中有一个名为 System 的类,并且你星号导入了另一个包,其中也有一个 System 类,如果你使用非限定类型,则选择该类在代码中的某处引用“System”?

    答案大概是,虽然规范对此很清楚,但几乎没有 Java 编码人员关心答案。他们宁愿……不要陷入这种奇怪的境地。因此,不要轻易使用星号导入,也不要将任何类命名为与java.lang 包中的类相同的类。

    如果一定要知道,顺序如下:

    将类型名称 System 解析为它所指的实际类型:

    1. 检查是否有命名(非星号)导入:import java.lang.System;
    2. 检查此源文件中是否有名为System 的类。
    3. 检查这个包中是否有一个名为System的类。
    4. 检查任何星号导入包中是否有一个名为 System 的类(因此,在 java.lang 中,因为它始终是星号导入的。

    因此,鉴于您的 System 类听起来像是在同一个包中,因此一个“获胜”。但是,如果在编译运行期间您的非测试源文件(您的 System.java 文件)不在类路径或源路径上,那么编译器不会直接告诉您这一点,而是您会看到您看到的错误。

    所以,你有两个问题:

    1. 您没有正确编译命令行上的测试类。使用构建系统。
    2. 不要将类命名为与 lang 包中的类相同;虽然您可以编写有效的代码,并且顺序定义明确,但它令人困惑(嘿,它让您感到困惑 - 那是那里的轶事证据!)而不是惯用的 java。其他人将很难阅读您的代码,并且您可能会在 IDE 等中遇到错误,因为当您在做奇怪的独特事情时,您遇到没有人想到也没有人跑的场景的几率会大大增加进入之前。

    【讨论】:

    • 感谢@rzwitserloot!是的,我的意思是 java.lang.System 不是 java.util。不幸的是,任务说明是创建一个名为 System 的类 - 我不会故意对自己这样做!我不确定我可以通过什么其他方式使用命令行编译它来解决这个问题?
    猜你喜欢
    • 2012-10-12
    • 2014-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多