让我们看看我们第一个Java程序.当运行时,下面的程序将在显示器上输出"Hello world!"
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
对于那些来自像Python这样的语言的人来说,这可能看起来过于冗长。但是,这都是有充分理由的,我们将在接下来的几周中了解到。请注意一些关键的语法特征:
- 程序由一个类声明组成,该类使用关键字public class声明。在Java中,所有代码都存在于类中。
- 运行的代码位于名为main的方法中,该方法声明为public static void main(String [] args)。
- 我们使用大括号{和}来表示代码段的开始和结束。
- 语句必须以分号结尾。
这不是一本Java教科书,因此我们不会详细介绍Java语法。如果您需要参考资料,请考虑Paul Hilfinger的免费电子书《Java参考》,或者如果您需要更传统的书籍,请考虑Kathy Sierra和Bert Bates的《Head First Java》。
看看其他语言中的Hello world!也很有趣。
运行Java程序
执行Java程序最常见的方法是通过两个程序的序列来运行它。第一个是Java编译器或javac。第二个是Java解释器或java。
例如,要运行HelloWorld.java,我们将在终端中键入命令javac HelloWorld.java,然后是命令java HelloWorld。结果将类似于下图:
$ javac HelloWorld.java
$ java HelloWorld
Hello World!
在上图中,$表示我们终端的命令提示符。您的可能会更长。
您可能会注意到,我们在编译时包括“.java”,但在解释时不包括“.class”。这就是它的方式(TIJTWII)。
练习1.1.1。在计算机上创建一个名为HelloWorld.java的文件,并复制并粘贴上面的确切程序。尝试使用javac HelloWorld.java命令。看起来好像什么也没发生。
但是,如果您查看目录,您将看到创建了一个名为HelloWorld.class的新文件。我们稍后将讨论这是什么。
现在尝试输入命令java HelloWorld。您应该在终端中看到“Hello World!”的输出。
只是为了好玩。尝试使用像Notepad、TextEdit、Sublime、vim或您喜欢的任何文本编辑器打开HelloWorld.class。您将看到只有Java解释器才能喜欢的许多疯狂垃圾。这是Java字节码,在我们的课程中不会讨论它。
变量和循环
下面的程序将打印从0到9
public class HelloNumbers {
public static void main(String[] args) {
int x = 0;
while (x < 10) {
System.out.print(x + " ");
x = x + 1;
}
}
}
当我们运行程序时,可以看到:
$ javac HelloNumbers.java
$ java HelloNumbers
$ 0 1 2 3 4 5 6 7 8 9
这个程序的一些有趣特点可能会引起您的注意:
- 我们的变量x必须在使用之前声明,并且必须赋予类型!
- 我们的循环定义包含在大括号内,测试的布尔表达式包含在括号内。
- 我们的打印语句只是System.out.print,而不是System.out.println。这意味着我们不应该包含换行符(回车)。
- 我们的打印语句在数字后面添加了一个空格。这可以确保数字不会相互重叠。尝试删除空格以查看会发生什么。
- 当我们运行它时,我们的提示符会出现在与数字相同的行上(如果您愿意,可以在以下练习中进行修复)。
- 这些特点中最重要的一个是变量具有声明类型的事实。我们稍后会回到这个问题,但首先是一个练习。
练习1.1.2。修改HelloNumbers,以便打印出从0到9的整数的累积和。例如,您的输出应该从0 1 3 6 10...开始,并以45结束。
此外,如果您有审美瘙痒,可以修改程序以便在结尾处打印出一个新行。
静态类型
Java最重要的特点之一是所有变量和表达式都具有所谓的静态类型。Java变量可以包含该类型的值,仅该类型的值。此外,变量的类型永远不会改变。
Java编译器的关键特点之一是它执行静态类型检查。例如,假设我们有以下程序:
public class HelloNumbers {
public static void main(String[] args) {
int x = 0;
while (x < 10) {
System.out.print(x + " ");
x = x + 1;
}
x = "horse";
}
}
编译该程序,可以看到:
$ javac HelloNumbers.java
HelloNumbers.java:9: error: incompatible types: String cannot be converted to int
x = "horse";
^
1 error
编译器在运行之前就拒绝了这个程序。这是一个很大的问题,因为这意味着在世界上运行此程序的人永远不会遇到类型错误!
这与Python等动态类型语言形成对比,在这些语言中,用户可以在执行期间遇到类型错误!
除了提供额外的错误检查之外,静态类型还让程序员知道他或她正在使用哪种对象。我们将在接下来的几周中看到这一点有多重要。这是我个人最喜欢的Java特性之一。
总之,静态类型具有以下优点:
- 编译器确保所有类型兼容,使程序员更容易调试其代码。
- 由于代码保证没有类型错误,因此编译后的程序用户永远不会遇到类型错误。例如,Android应用程序以Java编写,并且通常仅以.class文件(即编译格式)分发。因此,这些应用程序不应该因为类型错误而崩溃,因为它们已经被编译器检查过了。
- 每个变量、参数和函数都有一个声明类型,使程序员更容易理解和推理代码。
但是,我们将看到静态类型也具有缺点,这将在后面的章节中讨论。
额外练习
在Java里,我们可以这样写"System.out.println(5 + " ");"。但是在Python里,我们不能这样写"print(5 + "horse")",为什么呢?
请思考下面两个Java语句:
String h = 5 + "horse";
和
int h = 5 + "horse";
第一个会成功;第二个会给出编译器错误。由于Java是强类型语言,如果告诉它h是一个字符串,它可以连接元素并给你一个字符串。但是当h是一个整数时,它不能连接一个数字和一个字符串并给你一个数字。
Python不约束类型,它无法做出您想要的类型的假设。x = 5 +“horse”是一个数字?一个字符串?Python不知道。因此它会出现错误。
在这种情况下,System.out.println(5 +“horse”);,Java将参数解释为字符串连接,并打印出“5horse”作为结果。或者,更有用的是,System.out.println(5 +“ ”);将在“5”后打印一个空格。
System.out.println(5 + "10");会打印什么?510还是15?System.out.println(5 + 10);呢?
定义Java结构
在像Python这样的语言中,函数可以在任何地方声明,甚至可以在函数外部声明。例如,下面的代码声明了一个返回两个参数中较大值的函数,然后使用此函数计算并打印数字8和10中的较大值:
def larger(x, y):
if x > y:
return x
return y
print(larger(8, 10))
由于所有Java代码都是类的一部分,因此我们必须定义函数以使它们属于某个类。属于类的函数通常称为“方法”。我们将在整个课程中交替使用这些术语。与上面的代码等效的Java程序如下:
public class LargerDemo {
public static int larger(int x, int y) {
if (x > y) {
return x;
}
return y;
}
public static void main(String[] args) {
System.out.println(larger(8, 10));
}
}
这里的新语法是我们使用关键字public static来声明我们的方法,这是Python的def关键字的一个非常粗略的类比。我们将在下一章中看到声明方法的其他方法。
这里给出的Java代码确实看起来更冗长!你可能会认为这种编程语言会减慢你的速度,确实,在短期内会有所减慢。把所有这些东西都看作我们尚未理解的安全设备。当我们构建小程序时,所有这些都似乎是多余的。然而,当我们开始构建大型程序时,我们将会欣赏到所有额外的复杂性。
作为类比,使用Python进行编程有点像Dan Osman自由攀爬Lover's Leap。它可能非常快,但危险。相比之下,Java更像使用绳索、头盔等,在这个视频中。
编码风格、注释、Javadoc
代码可以以许多方式变得美丽。它可以简洁、聪明、高效。初学者中最不受欣赏的代码方面之一是代码风格。当你作为初学者编程时,你经常只是单纯地想让它工作,而不考虑以后是否要再次查看它或在长时间内维护它。
在本课程中,我们将努力保持我们的代码可读性。一些良好编码风格的最重要特征包括:
- 一致的风格(间距、变量命名、大括号风格等)
- 大小(行不要太宽,源文件不要太长)
- 描述性命名(变量、函数、类),例如变量或函数的名称为year或getUserName,而不是x或f。
- 避免重复的代码:你几乎永远不应该有两个几乎相同但除了一些更改之外的重要代码块。
- 适当的注释。Java中的行注释使用//分隔符。块(也称为多行注释)注释使用/和/。
黄金法则是:编写您的代码,使陌生人能够轻松理解。
这里是本课官方风格指引。值得读一读。
通常,我们愿意承担轻微的性能损失,只是为了让我们的代码更容易理解。我们将在后面的章节中举例说明。
注释
我们鼓励您编写自我记录的代码,即通过选择变量名和函数名使其易于知道正在发生什么。然而,这并不总是足够的。例如,如果您正在实现一个复杂的算法,您可能需要添加注释来描述您的代码。您的注释使用应该是明智的。通过经验和接触到其他人的代码,您会对何时使用注释有更好的感觉。
一个特别的注意事项是,所有的方法和几乎所有的类都应该使用所谓的Javadoc格式在注释中进行描述。在Javadoc注释中,块注释以额外的星号开始,例如/**,注释通常(但不总是)包含描述性标记。我们不会在本教材中讨论这些标记,但请参见上面的链接以了解它们的工作原理。
以下是一个没有标记的示例:
public class LargerDemo {
/** Returns the larger of x and y. */
public static int larger(int x, int y) {
if (x > y) {
return x;
}
return y;
}
public static void main(String[] args) {
System.out.println(larger(8, 10));
}
}
广泛使用的javadoc工具可以被用于生成HTML文件来描述你的代码。我们可以在最后一章节看到例子。
接下来
在本章最后,这里有几个链接让你知道,利用现有只是你可以完成什么联系,你应该完成这些。 Homework 0 Lab 1b Lab 1 Discussion 1