【问题标题】:Simple java code does not compile - "Create class 'Object' in type 'java.lang'"简单的 java 代码无法编译 - “在类型 'java.lang' 中创建类 'Object'”
【发布时间】:2014-11-17 19:06:16
【问题描述】:

以下代码无法编译(使用 eclipse Luna):

public class Main {
    public static void main(String[] args) {
        java.lang.Object Object = new java.lang.Object(); // Error line
        System.out.println(Object.class);
    }
}

class java {
    static lang lang;
}

class lang {
    static Object Object;
}

class Object {
    static java java;
}

Eclipse 自动建议我“在 'java.lang' 类型中创建类 'Object'”...

(我确实在构建路径中有 JRE)。

那么,我的代码有什么问题?

编辑:

错误出现在声明和实例化语句中。

编辑 2:

实例化java 仍然会产生同样的错误:

public class Main {
    public static void main(String[] args) {
        java java = new java();
        java.lang.Object Object = new java.lang.Object();
        System.out.println(Object.class);
    }
}

class java {
    static lang lang = new lang();
}

class lang {
    static Object Object = new Object();
}

class Object {
    static java java = new java();
}

【问题讨论】:

  • 嗯.. 为什么不呢?声明 java.lang.Object 实例有什么问题?
  • 删除底部的javalangObject类——你很困惑——这些是不需要的。
  • javalang 是包。而Object 已经作为一个类存在。我认为您需要更多地了解 Java 中的类和对象是如何工作的。
  • 我知道有包,但我仍然可以将类名声明为与包名相同,不是吗?
  • @Elist 你为什么要这样做?您在这里提出重大问题。此外,你的类中的静态变量都是空的。这可能会导致问题。你的课程是循环的。 java 包含 lang 包含 Object 包含 java 包含 lang ... 等等。这也可能导致问题。你到底想在这里做什么?如果我们知道您的目标,我们可以提供更好的帮助。

标签: java eclipse object compiler-errors


【解决方案1】:

您的问题是,通过定义一个名为 java 的类,您改变了 java.lang.Object 的含义 - 所以编译器现在将其视为语义不正确的东西,而不是将其视为 @987654323 的名称@类。

不要创建一个名为java 的类。它破坏了一切。

【讨论】:

  • 确实如此,不是吗? :0
【解决方案2】:
  1. 使用 Java 的标准命名约定,即大写类而不大写变量名。
  2. java.lang.Object已经存在,不用写了

    class java {
        static lang lang;
    }
    
    class lang {
        static Object Object;
    }
    
    class Object {
        static java java;
    }
    
  3. java.lang是隐式导入的,所以不用说

    java.lang.Object object = new java.lang.Object();
    

    你可以说

    Object object = new Object();
    

最终代码:

public class Main {
    public static void main(String[] args) {
        Object object = new Object();
        System.out.println(object.class);
    }
}

【讨论】:

    【解决方案3】:

    在这种情况下,您必须先实例化 java,然后才能访问它的子级,从而导致不那么优雅。

    public static void main(String[] args) {
        Object Object = (new java()).lang.Object; // instantiate java, THEN call lang.Object
        System.out.println(Object.getClass());
    }
    

    这会导致:

    线程“main”中的异常 java.lang.NullPointerException 在 Test.main(Test.java:4)

    这是预期的,因为 langnull 内的 java,因为您尚未为静态 lang 声明初始值。

    【讨论】:

    • @Elist 我的脑袋爆炸了。
    • 很高兴听到这个消息 ;)
    【解决方案4】:

    java 被定义为本地范围内的一个类,它优先于全局定义的 java 包。因此,当您的代码引用 java.lang.Object 时,编译器会将其理解为对 lang 类的静态 Object 属性的引用。对象是“对象”而不是类型,您的语法是非法的

    java.lang.Object Object = new java.lang.Object();  //this is illegal because java.lang.Object is an object, not a type
    
    Object o = java.lang.Object; //this is legal because you're just creating a reference to an object
    

    【讨论】:

    • 这意味着我永远不能在这个范围内声明一个对象(我的意思是常规 - 众所周知的对象)......你不觉得很麻烦吗?
    • @Elist 在我 5 年的企业 Java 编程中,没有。我从来不需要那样做。您可以完全控制命名局部变量的名称,因此可以尊重使您的代码正常工作的库所使用的名称:)
    • @AliCheaito 你的答案是错误的。 java.lang.Object Object = new java.lang.Object(); 本身就是完全有效的 Java;它不编译的唯一原因是@Elist 与他的班级名称阴影java。这是一个非常糟糕的主意。 Object o = java.lang.Object; 不是有效的 Java,除非您有 @Elist 添加的奇怪代码。在没有@Elist 代码的情况下在你的编译器中尝试两者,你会看到第一行有效,第二行无效。
    • @ErwinBolwidt 我的答案非常好,因为它完全基于 Elist 提供的代码。实际上,我在回答中解释了“名称阴影”效应,而没有使用花哨的术语。我从来没有说过 java.lang.Object Object = new java.lang.Object();是“本身不是完全有效的 Java”,我只是解释了为什么它在给定的代码中不起作用。请在投反对票前了解答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-15
    • 1970-01-01
    • 2013-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多