在我的项目中使用预定义的 class 名称字符串
using predefined class name String in my project
我有下面的代码,它会抛出下面给出的错误。当 'String[] args' 替换为 'java.lang.String[] args' 时,它不会抛出错误并运行方法 s1.method1().
问题:为什么本地字符串优先于 java.lang.String?
根据委派模型,Bootstrap class 加载程序获得优先权并在加载测试 class 之前加载 java.lang.String。我在这里错过了什么吗?请指出有关此行为的任何参考资料。
Test.java:
package diff;
class String {
public void method1(){
System.out.println("in my method");
}
}
class Test {
public static void main(String[] args){
String s1 = new String();
s1.method1();
}
}
错误:在classdiff.Test中找不到主要方法,请将主要方法定义为:
public static void main(String[] args)
或 JavaFX 应用程序 class 必须扩展 javafx.application.Application
问题:为什么本地字符串优先于 java.lang.String?
本地 name masks java.lang
中的那个。 java.lang
包由编译器为每个程序隐式导入,但是您不能将 java.lang.String
用作 String
因为您 屏蔽了 名称 String
。如您所述,您可以使用 java.lang.String
或 重命名您的 String
class (简而言之,不要添加自定义 classes与 java.lang
中的 class 个名称冲突)。这不是 class-loader 问题,因为编译后所有 classes 在字节码中都是完全合格的。
你必须区分类型和名称。您创建了一个名为 diff.String
的 class,它不会与 java.lang.String
发生冲突。 class 加载程序委托在这里无关紧要;甚至不可能定义冲突的 java.lang.String
class,因为以 java.
开头的名称是保留的。
当简单名称 String
得到解析时,本地范围具有优先权。顺便说一下,这发生在 compile-time,这是 class 加载器在这里不相关的另一个原因。还有一个优先规则,variable > class > package,它允许下面的怪异代码:
Integer String = 42;
String Integer = ""+String.intValue();
System.out.println(Integer);
第一个语句声明了一个名为 String
的 Integer
类型的变量。在第二个语句中,第一个“String
”被解析为一个类型,因为这个位置不允许使用变量,而对于名称的第二次出现,在 String.intValue()
中,变量 String
优先。同样,在第三条语句中,Integer
被解析为变量 Integer
.
一般来说,程序员应该遵循只让 class 名称以大写字母开头的约定,这大大减少了了解这些规则的需要。
要点是,并非每次出现简单名称 String
都暗示对类型 java.lang.String
的引用,甚至不能保证引用类型。上下文很重要。
我有下面的代码,它会抛出下面给出的错误。当 'String[] args' 替换为 'java.lang.String[] args' 时,它不会抛出错误并运行方法 s1.method1().
问题:为什么本地字符串优先于 java.lang.String? 根据委派模型,Bootstrap class 加载程序获得优先权并在加载测试 class 之前加载 java.lang.String。我在这里错过了什么吗?请指出有关此行为的任何参考资料。
Test.java:
package diff;
class String {
public void method1(){
System.out.println("in my method");
}
}
class Test {
public static void main(String[] args){
String s1 = new String();
s1.method1();
}
}
错误:在classdiff.Test中找不到主要方法,请将主要方法定义为: public static void main(String[] args) 或 JavaFX 应用程序 class 必须扩展 javafx.application.Application
问题:为什么本地字符串优先于 java.lang.String?
本地 name masks java.lang
中的那个。 java.lang
包由编译器为每个程序隐式导入,但是您不能将 java.lang.String
用作 String
因为您 屏蔽了 名称 String
。如您所述,您可以使用 java.lang.String
或 重命名您的 String
class (简而言之,不要添加自定义 classes与 java.lang
中的 class 个名称冲突)。这不是 class-loader 问题,因为编译后所有 classes 在字节码中都是完全合格的。
你必须区分类型和名称。您创建了一个名为 diff.String
的 class,它不会与 java.lang.String
发生冲突。 class 加载程序委托在这里无关紧要;甚至不可能定义冲突的 java.lang.String
class,因为以 java.
开头的名称是保留的。
当简单名称 String
得到解析时,本地范围具有优先权。顺便说一下,这发生在 compile-time,这是 class 加载器在这里不相关的另一个原因。还有一个优先规则,variable > class > package,它允许下面的怪异代码:
Integer String = 42;
String Integer = ""+String.intValue();
System.out.println(Integer);
第一个语句声明了一个名为 String
的 Integer
类型的变量。在第二个语句中,第一个“String
”被解析为一个类型,因为这个位置不允许使用变量,而对于名称的第二次出现,在 String.intValue()
中,变量 String
优先。同样,在第三条语句中,Integer
被解析为变量 Integer
.
一般来说,程序员应该遵循只让 class 名称以大写字母开头的约定,这大大减少了了解这些规则的需要。
要点是,并非每次出现简单名称 String
都暗示对类型 java.lang.String
的引用,甚至不能保证引用类型。上下文很重要。