1.1 要点 ·拥抱61B — 1.1 Essentials · Hug61B (gitbooks.io)

要点

Hello world

1
2
3
4
5
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}

System.out.println("Hello world!");相当于与c++中的cout<<"Hello world!"<<endl;

System.out.print("Hello world!");相当于与c++中的cout<<"Hello world!";

对于那些来自像 Python 这样的语言的人来说,这似乎毫无必要地冗长。然而,这一切都是有充分理由的,我们将在接下来的几周内理解这一点。需要注意的一些关键语法特征:

  • 该程序由一个类声明组成,该声明使用关键字 public class 声明。在 Java 中,所有代码都位于类中。
  • 运行的代码位于名为 main 的方法中,该方法声明为 public static void main(String[] args)
  • 我们使用大括号 { 和来表示一段代码的开头和 } 结尾。
  • 语句必须以分号结尾。

运行 Java 程序

执行 Java 程序的最常见方法是通过两个程序的序列运行它。第一种是 Java 编译器,或 javac .第二个是 Java 解释器,或 java .

![image-20240118035144027](2-CS61B学习笔记-Reading.1.Introducion to Java/image-20240118035144027.png)

例如,要运行 HelloWorld.java ,我们会在终端中键入命令,然后键入命令 javac HelloWorld.java java HelloWorld 。结果如下所示:

1
2
3
$ javac HelloWorld.java
$ java HelloWorld
Hello World!

在上图中,$ 表示我们终端的命令提示符。

您可能会注意到,我们在编译时包含“.java”,但在解释时不包括“.class”。这就是它的方式(TIJTWII)。

代码样式、注释、Javadoc

代码在很多方面都很漂亮。它可以很简洁。它可以很聪明。它可以是有效的。新手最不被重视的代码方面之一是代码风格。当你作为一个新手编程时,你往往一心一意地让它工作,而不考虑再看一遍或不得不长时间维护它。

在本课程中,我们将努力保持代码的可读性。良好的编码风格的一些最重要的特征是:

  • 一致的样式(间距、变量命名、大括号样式等)
  • 大小(行不要太宽,源文件不要太长)
  • 描述性命名(变量、函数、类),例如名称为 year or 而不是 x or f getUserName 的变量或函数。
  • 避免重复代码:除了一些更改外,几乎不应该有两个几乎相同的重要代码块。
  • 酌情注释。Java 中的行注释使用 // 分隔符。阻止(又名多行注释)注释 use /**/ .

黄金法则是:编写代码,以便陌生人易于理解。

Style Guide | CS 61B Spring 2019 (datastructur.es)这是该课程的官方风格指南。值得一看!

注释

所有方法和几乎所有类都应该使用所谓的 Javadoc 格式在注释中进行描述。在 Javadoc 注释中Javadoc - 维基百科,自由的百科全书 — Javadoc - Wikipedia,块注释以额外的星号开头,例如 /** ,并且注释通常(但并非总是)包含描述性标记。我们不会在本教科书中讨论这些标签,但请参阅上面的链接以了解它们的工作原理。

需要特别注意的是,所有方法和几乎所有类都应该使用所谓的 Javadoc 格式在注释中进行描述。在 Javadoc 注释中,块注释以额外的星号开头,例如 /** ,并且注释通常(但并非总是)包含描述性标记。我们不会在本教科书中讨论这些标签,但请参阅上面的链接以了解它们的工作原理。

举个没有标签的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
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 工具javadoc (oracle.com)可用于生成代码的 HTML 描述。

对象

定义和使用类

Java 中的所有代码都必须是类的一部分(或类似于类的东西,我们将在后面学习)。大多数代码都是在方法内部编写的。让我们考虑一个例子:

1
2
3
4
5
public class Dog {
public static void makeNoise() {
System.out.println("Bark!");
}
}

如果我们尝试运行该 Dog 类,我们只会收到一条错误消息:

1
2
3
$ java Dog
Error: Main method not found in class Dog, please define the main method as:
public static void main(String[] args)

我们定义的 Dog 类不执行任何操作。我们只是定义了一些 Dog 可以做的事情,即制造噪音。要实际运行该类,我们需要向 Dog 该类添加一个 main 方法,正如我们在第 1.1 章中看到的那样。或者我们可以创建一个单独的 DogLauncher 类来运行该 Dog 类的方法。例如,考虑以下程序:

1
2
3
4
5
public class DogLauncher {
public static void main(String[] args) {
Dog.makeNoise();
}
}
1
2
$ java DogLauncher
Bark!

使用另一个类的类有时称为该类的“客户端”,即 DogLauncherDog 的客户端。这两种技术都不是更好的:在某些情况下,添加 main 方法可能更好,而在其他情况下创建类似 client 类 Dog DogLauncher 可能更好。随着我们在整个课程中获得额外的练习,每种方法的相对优势将变得清晰。

因此总结下:

  • 类的使用有两种方法:
    • 一种是带有main方法的类
    • 一种是只有方法,由另一个类来调用。

静态方法 vs 非静态方法

cpp的知识点,静态方法属于类,非静态方法属于对象(实例)。调用静态方法时,通常用类名.方法,调用非静态方法时通常用对象名.方法

对比上下两个Dog类的makeNoise方法可以发现,在加上条件判断语句前为静态方法,加上后变为非静态方法,说明是不同体重对象的方法。

详细下面有说

实例变量和对象实例化

并非所有的狗都是一样的。有些狗喜欢不停地吠叫,而另一些狗则发出铿锵有力的咆哮,给所有听到它们光荣呼唤的人带来欢乐。通常,我们编写程序来模仿我们居住的宇宙的特征,而 Java 的语法很容易允许这种模仿。

允许我们表示 Dogdom 光谱的一种方法是为每种类型的 Dog 创建单独的类。

1
2
3
4
5
6
7
8
9
10
11
public class TinyDog {
public static void makeNoise() {
System.out.println("yip yip yip yip");
}
}

public class MalamuteDog {
public static void makeNoise() {
System.out.println("arooooooooooooooo!");
}
}

正如您过去应该看到的,类可以实例化,实例可以保存数据。这导致了一种更自然的方法,我们创建 Dog 类的实例,并使 Dog 方法的行为取决于特定 Dog .为了更具体地说明这一点,请考虑以下类:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Dog {
public int weightInPounds;

public void makeNoise() {
if (weightInPounds < 10) {
System.out.println("yipyipyip!");
} else if (weightInPounds < 30) {
System.out.println("bark. bark.");
} else {
System.out.println("woof!");
}
}
}

作为使用这种狗的例子,请考虑:

1
2
3
4
5
6
7
8
public class DogLauncher {
public static void main(String[] args) {
Dog d;
d = new Dog();
d.weightInPounds = 20;
d.makeNoise();
}
}

一些关键观察结果和术语:

  • Java 中的 Object 是任何类的实例。
  • Dog 类有自己的变量,也称为实例变量或非静态变量。这些必须在类中声明,这与 Python 或 Matlab 等语言不同,后者可以在运行时添加新变量。
  • 我们在 Dog 类中创建的方法没有关键字 static 。我们将此类方法称为实例方法或非静态方法。
  • 要调用该 makeNoise 方法,我们必须首先使用 new 关键字实例化 a Dog ,然后制作特定的 Dog bark。换句话说,我们调用 d.makeNoise()Dog.makeNoise() .
  • 一旦一个对象被实例化,就可以将其分配给适当类型的声明变量,例如 d = new Dog();
  • 类的变量和方法也称为类的成员。
  • 使用点表示法访问类的成员。

类方法与实例方法

Java 允许我们定义两种类型的方法:

  • 类方法,又名静态方法。
  • 实例方法,又名非静态方法。

实例方法是只能由类的特定实例执行的操作。静态方法是由类本身执行的操作。两者在不同情况下都很有用。作为静态方法的示例,该 Math 类提供了一个 sqrt 方法。因为它是静态的,我们可以这样称呼它:

1
x = Math.sqrt(100);

如果 sqrt 是一个实例方法,我们将得到下面笨拙的语法。幸运的是,它是一种 sqrt 静态方法,因此我们不必在实际程序中执行此操作。

1
2
Math m = new Math();
x = m.sqrt(100);

有时,拥有一个同时具有实例和静态方法的类是有意义的。例如,假设想要比较两只狗的能力。一种方法是添加一个用于比较 Dogs 的静态方法。

1
2
3
Dog d = new Dog(15);
Dog d2 = new Dog(100);
Dog.maxDog(d, d2);

请注意,我们已使用类名调用,因为此方法是静态方法。

我们也可以 maxDog 实现为非静态方法,例如

1
2
3
4
5
6
public Dog maxDog(Dog d2) {
if (this.weightInPounds > d2.weightInPounds) {
return this;
}
return d2;
}

上面,我们使用关键字 this 来指代当前对象。例如,可以使用以下方法调用此方法:

1
2
3
Dog d = new Dog(15);
Dog d2 = new Dog(100);
d.maxDog(d2);

静态变量

类具有静态变量有时很有用。这些是类本身固有的属性,而不是实例的属性。例如,我们可以记录狗的学名(或双子)是Canis familiaris

1
2
3
4
5
public class Dog {
public int weightInPounds;
public static String binomen = "Canis familiaris";
...
}

静态变量应该使用类的名称而不是特定的实例来访问,例如,您应该使用 Dog.binomen ,而不是 d.binomen .

虽然 Java 在技术上允许你使用实例名称访问静态变量,但它的风格很糟糕,令人困惑,而且在我看来是 Java 设计者的错误。(不是我的评价)

Java的构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Dog {
public int weightInPounds;

public Dog(int w) {
weightInPounds = w;
}

public void makeNoise() {
if (weightInPounds < 10) {
System.out.println("yipyipyip!");
} else if (weightInPounds < 30) {
System.out.println("bark. bark.");
} else {
System.out.println("woof!");
}
}
}

每当我们尝试 Dog 创建 using new 关键字和单个整数参数时,都会调用带有签名 public Dog(int w) 的构造函数。对于那些来自 Python 的人来说,构造函数与 __init__ 方法非常相似。

数组实例化,对象数组

1
2
3
4
5
6
7
8
9
10
11
public class DogArrayDemo {
public static void main(String[] args) {
/* Create an array of two dogs. */
Dog[] dogs = new Dog[2];
dogs[0] = new Dog(8);
dogs[1] = new Dog(20);

/* Yipping will result, since dogs[0] has weight 8. */
dogs[0].makeNoise();
}
}

请注意,new 以两种不同的方式使用:一次用于创建一个可以容纳两个 Dog 对象的数组,两次用于创建每个实际 Dog 的 .

public static void main(String[] args)的说明

根据我们目前所学到的知识,是时候揭开我们一直用于 main 方法的声明的神秘面纱了。把它分成几块,我们有:

  • public :到目前为止,我们所有的方法都以这个关键字开头。
  • static` :它是一个静态方法,不与任何特定实例关联。
  • void :它没有返回类型。
  • main :这是方法的名称。
  • String[] args :这是传递给 main 方法的参数。

命令行参数

由于 main 是由 Java 解释器本身调用的,而不是由另一个 Java 类调用的,因此解释器的工作是提供这些参数。它们通常引用命令行参数。例如,考虑以下程序 ArgsDemo

1
2
3
4
5
public class ArgsDemo {
public static void main(String[] args) {
System.out.println(args[0]);
}
}

该程序打印出第 0 个命令行参数,例如

1
2
$ java ArgsDemo these are command line arguments
these

在上面的示例中,将是一个字符串数组, args 其中条目为 {“these”, “are”, “command”, “line”, “arguments”}。

这样子可以识别命名 -m -v 等