我还在学习,并注意到编码方面存在许多不一致之处。 我认为Java非常像Photoshop,可以通过多种方式完成单个任务,并且仍然可以完成工作。
我的主要问题之一是Scanner和Random。
在一个来源中,他们在全班的范围内拥有Scanner
public class test {
private static Scanner input = new Scanner(System.in);
}
在另一个来源中,他们就像这样
public class test {
private static Scanner input;
public static void main(String[] args) {
input = new Scanner(System.in);
}
}
与此有什么不同?有正确的方法和错误的方式吗?
答案 0 :(得分:1)
这里有区别!
如果要在不调用任何方法的情况下访问扫描仪,请将其放在字段或静态块中。
你的例子
private static Scanner input = new Scanner(System.in);
仅等于此
private static Scanner input;
static {
input = new Scanner(System.in);
}
初始化时间不同。方法main
是一种不可见的特殊方法,因为此方法启动您的程序;)
答案 1 :(得分:1)
您初始化Scanner
的两种方式相似,但不完全相同。
第一个始终有效,因为您在创建static
变量时正在初始化它。
第二个仅在test
是启动类时有效,因为public static void main(String[] args)
总是在应用程序的启动类中调用。
如果您尝试使用其他类中的test
类的方法,则会出现问题,如下所示:
public class test {
private static Scanner input;
public static void main(String[] args) {
input = new Scanner(System.in);
}
public static void myMethod() {
input.hasNext();
}
}
并在单独的文件中
public class AnotherTest {
public static void main(String[] args) {
test.myMethod();
}
}
只要您运行java AnotherTest
,它就会input.hasNext()
上的NullPointerException
爆炸,因为test
的{{1}}永远不会被运行,因此{永远不会初始化{1}}。
编辑:旁注,Java中的类名几乎总是大写。
答案 2 :(得分:1)
你是对的,肯定有很多方法可以解决问题同样适用于某些用例。
在您的示例代码中,唯一的区别基本上是在类生命周期中的什么时间静态变量获取向其声明的值,即scanner对象。
将静态视为类的一部分,即模板,而不是使用类构造的对象作为其外观和功能的模板。
我相信当你需要考虑启动变量的位置和时间时,有两个很好的理由。 一个是线程安全问题。 “几个线程能够访问同一个类成员,扫描器吗?”在方法之外声明的变量在方法外部是不可访问的,任何其他线程也无法访问它。
另一个原因是设计和结构。我们都希望代码具有良好的易读性和易懂性。对于阅读代码的人来说,哪个更清楚?
当然,在考虑设计和结构之前,必须考虑线程安全问题。仅仅因为当在类级别声明所有变量时,读取某些代码会更容易,如果它使应用程序失败,则不一定要编写代码。
答案 3 :(得分:0)
最终,您编写的代码不是计算机在运行程序时执行的代码。如果它是像Python或Lua这样的解释语言,但是使用编译语言(没有涉及Java特殊的方式),语言实际上被编译器程序完全转换为机器代码中完全不同的程序
因此,在许多情况下,您可以用几种不同的方式编写代码,编译器最终会以相同的方式写出机器代码。
这里有静态变量的区别,因为它们是立即初始化的,但是这里的区别主要是样式和外观,不要太担心它。编译器将理解两者并产生大致相同的代码。
未初始化的变量设置为默认值(对象为null),然后在构造函数中设置,并且在初始化期间设置它们可能稍微有点效率。
最终值应该初始化并且是静态的,否则主要取决于您的偏好。