eclipse里的无参构造_MIT 6.031 | 软件构造:Java 基础

这是国庆假期系列的第一篇。

6.031 软件构造

安装

这门课需要 JDK14,Eclipse 和 Git。

Eclipse 安装

首先到 https://www.oracle.com/java/technologies/javase-jdk14-downloads.html 下载 JDK14。

然后到 https://www.eclipse.org/downloads/ 下载 eclipse 安装程序。

  • 运行安装程序,选 ADVANCED MODE,使用 URL https://raw.githubusercontent.com/6031/eclipse031/master/setup/eclipse-for-6031.setup
  • 应该自动选择 Java 14,如果没有的话请手动选择
  • Next,不选择任何项目
  • Next,选择安装位置,Finish

Eclipse 配置

打开 Preferences

  • 打开 Java -> Installed JREs,确保使用的是 Java SE 14 或者 14.0.2
    • 打开 Edit..,在 Default VM arguments 输入 -ea,Finish
  • 打开 Java -> Compiler,把 compiliance level 设置成 14
  • Apply and Close

Git 安装

Git 在 https://www.git-scm.com/ 下载安装。

# git --version
git version 1.8.3.1
# git config --global user.name "username"
# git config --global user.email username@mail.somewhere.edu.cn
# git config --global alias.lol "log --graph --oneline --decorate --color --all"
# git config --list

Github

Github 是一个远程存放 Git repo 的网站。

登录 Github 后,你可以在 Settings -> SSH and GPG keys 页面

Git 操作

clone

# git clone URI-of-remote-repo
# git clone URI-of-remote-repo repo-name

commit

# git add file-name
# git commit

如果你 add 了但是没有 commit,可以

# git status

diff

# git diff
# git diff --staged

工作流

# git pull
# do something
# git add something
# git push

查看记录

# git log
# git show

先修

在 MIT,这门课的先修是 6.009 Foundamentals of Programming,也就是基本的 Python 编程。

如果之前的编程经验较少,需要在 6.031 中加倍的努力。

如果学习 Java 有困难,可以去看 OCW 6.092 或者 Codecademy Java。

内容

  • 静态检查
  • Java 基础
  • 代码审查
  • 测试
  • 版本控制
  • Specifications
  • 可变性与不变性
  • 避免调试
  • 抽象数据类型
  • 抽象函数和表示不变性
  • 使用接口、泛型、枚举和函数定义抽象数据类型
  • 调试
  • 递归
  • 等价性
  • 递归数据类型
  • 正则表达式
  • 解析器
  • 使用抽象数据类型写程序

资料

  • Java API,https://docs.oracle.com/en/java/javase/14/docs/api/
  • Codecademy Java,https://www.codecademy.com/learn/learn-java/modules/learn-java-hello-world/cheatsheet

静态检查

Hailstone 序列

我们以 Hailstone 序列为例子,这个序列从 n 开始,到 1 结束

  • 如果 a[n] 是偶数,那么 a[n+1]=a[n]/2
  • 如果 a[n] 是奇数,那么 a[n+1]=3*a[n]+1

我们可以这样计算这个序列

int n = 7;

while (n!=1) {
    System.out.printf("%d, ", n);
    if (n%2 == 0) {
        n = n / 2;
    } else {
        n = 3 * n + 1;
    }
}

System.out.printf("1");

类型

Java 和 Python 最大的不同是,当我们声明一个变量的时候我们要声明类型

int n = 7;

一个类型是值的集合,同时还定义了一些作用在这些值上的操作。

Java 的 primitive types,例如

  • int,4 字节
  • long,8 字节
  • boolean
  • double
  • char

Java 的 object types,例如

  • String
  • BigInteger

静态类型

Java 是一门静态类型的语言。所有变量的类型在编译时就已经知道了。而动态类型语言,比如 Python,要到运行时才知道变量的类型。

静态类型是静态检查的一种,静态检查指在编译时检查程序有没有 Bug。这门课的主要内容就是如何避免软件存在 Bug,而静态检查是我们做的第一步。

动态类型语言的静态类型支持

比如 PEP 484,Type Hints,https://www.python.org/dev/peps/pep-0484/。

从 Python 3.5 开始支持声明 type hints,例如

def hello(name:str)->str:
    return 'Hi, ' + name

像 mypy(http://mypy-lang.org/) 之类的 checker 会在程序运行之间检查有没有静态错误。

再比如 Typescript

function hello(name:string):string {
    return 'Hi, ' + name;
}

这种支持显示出软件工程师的一种普遍共识:使用静态类型是构建和维护大型软件系统的基础。接下来我们会解释这种共识的理由。

与 Java 这种静态类型的语言不同,给动态类型语言提供静态类型支持,这种方法又被称为 Gradual typing。也就是说程序里有的部分有静态类型声明,有的部分没有。Gradual typing 提供了一种,从小的实验原型构造大型稳定可维护系统的,更平缓的路径。

静态检查,动态检查

静态检查是指在程序运行之前找 Bug。

  • 语法错误
  • 拼错的名字
  • 参数数量/类型错误
  • 返回类型错误

动态检查是指在程序运行的过程中找 Bug。

  • 不合法的值
  • 不合法的转换
  • 越界
  • 调用 null 对象引用的方法

大体来说,静态检查是和类型有关的。

另外,在 Java 和很多编程语言中,数字类型和我们熟悉的整数/实数概念不同。这可能导致有一些我们希望动态检查的错误查不出来,比如

  • 整数除法,5/2 会得到 2
  • 整数溢出
  • 浮点型的特殊值,比如 NaNPOSITIVE_INFINITENEGATIVE_INFINITY

数组和集合

数组是一种固定长度的序列

int[] a = new int[100];
// a[2]
// a[2] = 0
// a.length

List 是一种可变长度的序列

List list = new ArrayList();// list.get(2)// list.set(2)// list.size()

注意 List 是一个接口,ArrayList 是一个类,实现了 List 这个接口。而 ArrayList 则是因为 Java 要求在参数化一个类型的时候必须使用对象类型而不是基本类型。

List list = new ArrayList();int n = 3;while (n != 1) {
    list.add(n);if (n % 2 == 0) {
        n = n / 2;
    } else {
        n = 3 * n + 1;
    }
}
list.add(n);

迭代

List 可以这样迭代

int max = 0;
for (int x : list) {
    max = Math.max(x, max);
}

方法

Java 里,语句都在一个方法内,方法都在一个类内。

所以 hailstone 程序可以写成

public class Hailstone {
    /**
     * Compute a hailstone sequence.
     * @param n  starting number for sequence; assumes n > 0.
     * @return hailstone sequence starting with n and ending with 1.
     */
    public static List hailstoneSequence(int n) {
        List list = new ArrayList();while (n != 1) {
            list.add(n);if (n % 2 == 0) {
                n = n / 2;
            } else {
                n = 3 * n + 1;
            }
        }
        list.add(n);return list;
    }
}

其中 public 表示任何代码,你的程序中的任何地方,都可以使用这个类或者方法。而 private 就有更好的安全性,保证不可变类型的不可变性。

其中 static 表示这个方法并不把 self 作为参数传入,或者在 Java 里叫 this

改变/再分配

改变是必要的恶,好的程序员应该极可能避免改变。

如果一个参考是不会被改变的,可以用 final

final int n = 5;

final 可以在静态检查中检查你有没有做 reassignment。

这门课的目标

  • safe from bugs
  • easy to understand
  • ready to change

Java 基础

快照图

快照图很好用

int n = 1;
double x = 3.5;

0f988081b0819b3a444958ce167ce0e7.png

BigInteger val = new BigInteger("123456789");

62c25166665bd746be6d50b6708e3eef.png

String s = "hello";

25edf4580d5d4b70204ba24bb697ba6e.png

Point pt = new Point(5, -3);

91547ea6002dfc50301fc40ad03682f5.png

String s = "a";
s = s + "b";

74bf2644291bc7d49a7fcb7b2fc8e917.png

StringBuilder sb = new StringBuilder("a"); sb.append("b");

f03973fa02a5fb4aeffc78187679ec54.png

final int n = 5;

8be3e9104b67984cb7635ac204bd34a5.png

final StringBuilder sb = new StringBuilder("a");
sb.append("b");

89701e0a17005cd153ff36341d5156f2.png

String s = "a";
s = "ab";

a4bd43580c71f88cf56974350cf90a99.png

==/.equals

对于基本类型,应该用 ==,对于对象,应该用 .equals()

8ffbc72ed029ea9afa432500de239464.png

  • x == y, true
  • x == z, false
  • x.equals(y), true
  • x.equals(z), true

Java 集合

List

Java 的 List 和 Python list 很像。

  • int count = lst.size()
  • lst.add(e)
  • if (lst.isEmpty()) ...
  • lst.contains(e)

83a7c46a17aad692d96de180ab311c8c.png

Map

Map 很像 Python 的 dictionary。

  • map.put(key, val)
  • map.get(key)
  • map.contains(key)
  • map.remove(key)

ea70b10a2ef5e7063e53abf200af7e78.png

Set

Set 是一个无序的集合,并且里面的元素互异,有点像 Python set。

  • s1.contains(e)
  • s1.containsAll(s2)
  • s1.remove(s2)

7a81734e7452a3b7e6487676cf0e0a6a.png

Literals

在 Java 里,这样只能创建 array,不能创建 list

String[] arr = {"a", "b", "c"};

要创建 list 必须这样

List.of("a", "b", "c");

但是要注意,通过 List.of() 创建的对象是不可变的。所以 add, remove, replace 都是不可以的。

另外我们还有

Set.of("a", "b", "c");
Map.of("apple", 5, "banana", 7);

泛型

在 Java 里,我们可以限制集合中元素的类型,这样就可以做静态检查

List cities;

虽然必须用对象类型来写泛型,但是下面这种情况会自动转换

sequence.add(5);
int second = sequence.get(5);

ArrayList 和 LinkedList

ListSetMap 都是接口,它们定义了对应的类型如何工作,但是并没有给出实现代码。

比如 List 的实现

List firstNames = new ArrayList();
List secondNames = new LinkedList();

还可以简写

List firstNames = new ArrayList<>();
List secondNames = new LinkedList<>();

刚才我们说 List.of() 会创建不可变的对象,如果需要可变的可以

List firstNames = new ArrayList<>(List.of("a", "b", "c"));

HashSet 和 HashMap

如果需要一个 Set

Set numbers = new HashSet<>();

如果需要有序集合

SortedSet numbers = new TreeSet<>();

如果需要一个 Map

Map turtles = new HashMap<>();

迭代

List, Set 可以做迭代

// List cities = new ArrayList<>();
for (String city : cities) {
    System.out.println(city);
}
// Set numbers = new HashSet<>();
for (int num : numbers) {
    System.out.println(num);
}

Map,我们可以对 key 做迭代

// Map turtles = new HashMap<>();
for (String key : turtles.keySet()) {
    System.out.println(key + ": " + turtles.get(key));
}

注意,如果在迭代过程中发生了改变,迭代会中断。

枚举

Java 支持用 enum 来构造枚举

public enum Month { 
    JANUARY, FEBRUARY, MARCH, APRIL, 
    MAY, JUNE, JULY, AUGUST, 
    SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER;
}

public enum PenColor { 
    BLACK, GRAY, RED, PINK, ORANGE, 
    YELLOW, GREEN, CYAN, BLUE, MAGENTA;
}

然后就可以

public static void main(String[] args){
    PenColor drawingColor;
    drawingColor = PenColor.BLACK;
    System.out.println(drawingColor);
}

注意初始化和赋值要分开,这样才能做静态检查。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
org.eclipse.aether.resolution.ArtifactResolutionException: Failure to find jre:jre:zip:call:1.0.0-SNAPSHOT in http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453) at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:255) at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:232) at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:303) at org.eclipse.recommenders.models.ModelRepository.resolveInternal(ModelRepository.java:193) at org.eclipse.recommenders.models.ModelRepository.resolve(ModelRepository.java:172) at org.eclipse.recommenders.internal.models.rcp.EclipseModelRepository.resolve(EclipseModelRepository.java:168) at org.eclipse.recommenders.internal.models.rcp.DownloadModelArchiveJob.run(DownloadModelArchiveJob.java:76) at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) Caused by: org.eclipse.aether.transfer.ArtifactNotFoundException: Failure to find jre:jre:zip:call:1.0.0-SNAPSHOT in http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.newException(DefaultUpdateCheckManager.java:240) at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.checkArtifact(DefaultUpdateCheckManager.java:215) at org.eclipse.aether.internal.impl.DefaultArtifactResolver.gatherDownloads(DefaultArtifactResolver.java:594) at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:512) at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:430) ... 8 more
07-12

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值