20145335郝昊《Java程序设计》第5周学习总结
教材学习内容总结
第八章
-
语法与继承架构
- 使用try、catch
-
特点:
- 使用try、catch语法,JVM会尝试执行try区块中的程序代码。如果有错误发生,会跳离错误发生点,执行catch区块中的代码。
- 执行完catch区块后,没有其他程序代码,程序就会结束。 -
注意:
- 在java中,所有的错误都会被打包成为对象。而try、catch是在发生了InputMismatchException的错误。(实际上并不鼓励,在异常继承架构分析。)
-
- 异常继承架构
- 特点:
- 设计错误的对象都继承自java.lang.Throwable类,其有两个子类java.lang.Error与java.lang.Exception
- Error错误:JVM内部的严重问题。无法恢复。程序人员不用处理。
- Exception异常:普通的问题。通过合理的处理,程序还可以回到正常执行流程。要求编程人员要进行处理。
- RuntimeException:也叫非受检异常。这类异常是编程人员的逻辑问题。java编译器不进行强制要求处理。也就是说,这类异常在程序中,可以进行处理,也可以不处理。
- 非RuntimeException:也叫受检异常。这类异常是由一些外部偶然因素所引起的。java编译器强制要求处理。也就是说,程序必须进行对这类异常的处理。
- 如果是检受异常,可由方法的客户端依据当时调用的环境信息进行处理,必须使用throws声明此方法会抛出的异常类或父亲类。
- 如果是非受检异常,原本就可以自行选择石佛偶处理异常,也不用特别在方法上使用throws声明。
- 如果某个方法声明会抛出Throwable或子类实例,只要不是属于Error、java.langRuntimeException或其子类实例,就必须明确使用try、catch语法加以处理,或者用throws声明这个方法会抛出异常。 - 注意:
- Error与其子类实例代表严重的系统错误,其对象抛出时,基本不用处理,任其传播至JVM为止,或者最多留下日志信息。
- 使用try、catch捕捉异常对象时也要注意,如果父类异常对象在子类异常前被捕捉,则catch子类异常对象的区块永远不会被执行。
- catch括号中列出的异常不得有继承关系,否则会发生编译错误。
- java是唯一采用受检异常的语言,一是为了文件化,客户端只要查阅文件,就可以知道哪些方法可能发生异常;二是提供编译程序信息,让编译程序能够在编译时期就检查出API客户端没有处理异常。
- 特点:
- 使用try、catch
-
关于抓和抛:
-
特点:
- 如果编译程序会抛出受检异常,无法使用try、catch处理时,必须使用throws声明此方法会抛出的异常类型或父类型,编译程序才会让你通过编译。
- 如果抛出非受检异常,在java中的设计上认为,非受检异常是程序设计不当引发的漏洞,异常应自动往外传播
- 实际上,先可使用try、catch处理完部分错误后,可以使用throw抛出。
- 重新抛出异常时,如果认为调用API的客户端应当有能力处理未处理的错误,就自定义受检异常、填入适当错误信息并重新抛出,并在方法上使用throws加以声明;如果认为调用API的客户端没有准备好就调用了方法,才会造成还有未处理的错误,就自定义非受检异常、填入适当错误信息并重新抛出。
-
注意:
- 先处理后抛出的时候是使用throw不是throws。
- 在自定义类别的时候通常建议继承自Exception或其子类。
- 在流程中要抛出的异常,也要思考一下,关键在于这是客户端可以处理的问题吗?还是客户端没有准备好前置条件就调用方法,才引发的异常?
-
-
认识堆栈追踪
-
特点:
- 采用直接调用异常对象的printStackTrace()
- 善用堆栈追踪,不可有私吞异常的行为、对异常做了不当的处理。
- 在使用throw重抛异常时,异常的追踪堆栈起点,任然是异常发生的根源。
-
注意:
- 如果想要让异常堆栈成为重抛异常的地方,可以使用fillInStrackTrace()方法,这个方法会重新装填异常堆栈,将起点设为重抛异常的地方,并返回Throwable对象。
-
-
关于assert:
- 是一种断言,预期结果与实际程序状态相同,断言成立,否则断言不成立。在java中使用-enableassertions或者是-ea自变量在执行时启动断言检查。 - assert有两种使用方法 1. assert boollean_expression;2. assert boolean_expression:detail_pression - checkGreatThanZero()是一种前置条件检查,如果程序上线之后就不需要这种检查的话,可以将之assert取代。 - charge()方法中使用了批注来提示方法调用后的对象状态必不可义为负,不如使用assert取代。
-
异常与资源管理
-
概念:
- 程序因错误而抛出异常时,原本的执行流程就会中端,如果程序开启了相应得资源,应该在使用完后关闭资源。
-
特点:
- 使用法finally,try、catch可以搭配finally区块使用。且该区块一定会被执行。
- 可以先检查scanner是否为null,仔调用close()方法关闭Scanner。
- 尝试关闭语法资源可套用的对象,必须操作java.lang.AutoClothesable接口
- 尝试关闭语法资源可以同时关闭两个以上的对象资源,只要中间以分号分割。
-
注意:
- 如果撰写的流程中线先return,而且也有finally区块,那finally区块会先执行后再将值返回。
- 尝试自动关闭资源的对象,是撰写在try之后的括号中。
- 在try括号中,越后面撰写的对象的资源会越早关闭。
-
第九章
-
使用Collection收集对象
-
了解Collection架构
- 在使用满足各种需求的API前,需要先了解其继承与接口操作,才能了解何时采用哪个类,以及类间如何彼此合作。
- 可以清楚地明了哪些类操作了哪个接口,继承了那个类,或哪些接口又继承自哪个接口。总之可在API文件上查询。
-
具有索引的List
1. 特点: - 是一种Collection,收集对象,并以索引的方式保留收集的对象顺序。 - java.util.ArrayList,数组在内存中会是连续的线性空间,根据索引随机存取时速度较快。 - LinkedList在操作List接口,才用了连接结构。 - 在每次add()对象时,会建立新的Node来保存对象,不会事先消耗内存。 1. 注意: - ArayList如果需要调整索引顺序时,会有较差的表现,使用ArrayList操作此类并不经济。 - 如果收集的对象经常会有变动索引的情况,也许考虑链接方式操作的List比较合适。
-
内容不重复的set
1. 特点:
- 在收集过程中若有相同对象,则不在重复收集。
- String的split(),可以指定切割字符串的方式。
- 调用set的size()方法,就可以知道收集的字符串个数。
- HashSet的toString()操作,会包括收集的字符串。
- 会使用对象hashcode()与equals()来判断对象是否相同。
1. 注意:- 如果同一个哈希桶已有对象,调用该对象equals()与要加入的对象比较,结果为false则非重复,给予收集true表示两个是重复对象,不予收集。
-
支持队列操作的Queue
- 如果希望收集对象时以队列的方式,收集的对象加入至尾端,取得对象是从前端。 - 自己定义了offer()、poll()、peek()等。这些方法在操作失败的时候会返回特定的值。 - Queue的子接口Deque定义了对队列的前端与尾端进行操作,在前端加入对象与取出对象,在尾端加入或取出对象。 - Queue自己定义了addFirst()、removeFirst()、getFirst()、addLast()、removeLast()、getLast()等方法。同样在其操作失败时返回特殊值。
-
使用泛型和lambda表达式
1. 特点: - 不知道被收集对象的形态,在内部操作时,都是使用Object来参考被收集的对象。取回对象时也是以Object类型返回。 - 泛型语法支持API时可以指定类或方法支持泛型类名称。 - 在类名称旁用角括号表示支持此类泛型。 - lambda表达式注意符号->左边是参数列,右边是方法本体。(如果是单参数又无须写出参数的类型时候()可以省略) 1. 注意: - 书上的例子角括号中的E只是一个类型代表。 - 这类API没有指定类型参数实际类型,程序代码中出现类型参数的地方就会回归使用Object类型。 - 使用lambda表达式,编译程序在推断类型时候,还可以使用泛型声明的类型作为信息来源。
-
Interable与Iterator
- iterator()方法,定义在Collection。该方法会返回java.util.Iterator接口操作对象,这个对象包括了Collection收集的所有的对象,可以使用Iterator的hasNext()看看有无下一个对象,若有的话在使用next()取得下一对象。可使用forEach()来收集对象。 - JDK5之后,将iterator()方法,提升至新的java.util.Iterable父接口。实际上还是调用了iterator()方法,运用返回的Iterator对象来迭代取得收集的对象。
-
Comparable与Comparator
1. 操作Comarable - Collection的sort()方法必须操作java.lang.Comparable接口,接口有个方法compare()方法如果a对象顺序小于b对象顺序返回小于0的值,若顺序上相等则返回0,若顺序上a大于b则返回大于0的值。 - set的操作类之一java.util.TreeSet不仅拥有收集不重复对象的能力,还可以用红黑树方式排序收集的对象,但条件必须是Comparable。 - Queue的操作类之一java.util.PriorityQueue收集至PriorityQueue的对象,会根据指定的优先权来决定对象在对列中的顺序,优先权的告知,对象必须是Comparable或者是创建PriorityQueue时指定Comparator对象。 1. 操作Comparator - 接受java.util.Comparator接口操作对象,根据caompare()决定。其会传入两个对象,如果o1顺序上小于o2则返回小于0的值,顺序相等则返回0的值,顺序上o1大于o2则返回大于0的值。
-
键值对应的Map
- 特点:
- 事先利用java.util.Map接口的操作对象来建立键值对应数据。
- 常用的Map操作类为Jjava.util.HashMap与java.util.TreeMap,其继承自抽象类java.util.AbstractMap。
- HashMap,要建立键值对应,可以使用put()方法,第一个自变量是键,第二个自变量是值。对于Map而言,键不会重复,判断是否重复根据hashCode()与equals()。
- TreeMap,键的部分将被排序,条件是作为键的对象必须操作Comaprable接口,或者是在创建TreeMap时指定Comparator接口对象。
- Properties的setProperty()指定字符串类型的键值,getProprty指定字符串类型的键,取回字符串类型的值,通常称为属性名称与属性值。
- 可以使用getProperties()取得ProPerties实例。
- 如果想要取得Map中所有的键,可以调用Map的KeySet()返回Set对象。
- 如果想取得Map所有的值,可以使用values()返回Collection对象。
- 如果想同时取得Map的键与值,可以使用entrySet()方法,这会返回一个Set对象,每个元素都是Map.Entry实例,可以调用getKey()取得键,调用getValue()取得值。
- 注意:
- .properties的=左边设定属性名称,右边设定属性值。
- 除了可载入.properties文档外,也可以使用loadfromXML()方法加载.xml文档,必须注意文件格式。
- 特点:
教材学习中的问题和解决过程
第八章
-
不太懂Exception和RuntimeExcepiton之间的关系,导致在区分受检异常和非受检异常存在着问题,以及后面的抛出关系区分不清楚。后来经过上网百度,查询知道并且区分清了两者的关系。这样对于判断受检异常与非受检异常容易许多。
-
关于堆栈追踪,没有理解清楚其之间的方法的用处,通过看书上的代码,并且自己尝试编译,发现理解了许多。
-
使用finally关闭资源方面,没有准确的理解finally区块的作用,在做课后习题的时候哦发现自己做的答案和用电脑编译的结果是不一样的,后来发现书上在撰写流程中有return,而且也有finally区块,那finally区块会先执行完后,再将值返回。
第九章
-
对于Collection架构了解不是很透彻,哪个口继承哪个口,哪个又操作了架构,后来看了书上的架构图后就有了很详细的了解了。明白了List()、Set()、Queue()等方法的使用。
-
关于泛型语法,起初没有掌握好用法和写法。后来照着书上ArrayList的实例后加深了印象,有了了解。
-
关于Map的键和值,没有区分清楚键和值的区别,导致在方法的使用上出现了错误,在编译的时候出现了问题,后来仔细看书,分清了KeySet()等方法。比如可以调用getKey()取得键,调用getValue()取得值。
代码调试中的问题和解决过程
package cc.openhomenine;
import java.util.*;
interface Request{
void execute();
}
public interface ResquestQueue {
public static void main (String[] args){
Queue request = new LinkedList();
offerRequestTo(request);//这里
process(request);//这里
}
static void offerRequestTo (Queue requests){
for (int i =1;i<6;i++){
Request request = new Request(){
public void execute(){
System.out.printf("处理数据 %f%n", Math.random());
}
};
requests.offer(request);
}
}
static void process(Queue requests){
while(requests.peek() != null){
Request request = (Request) requests.poll();
request.execute();
}
}
}
这个代码在上框中的其中语法OfferRequestTo(requests);和
processs(requests);括号中都是requests,但是使用eclipse编译的时候是没有通过的
但将括号中的requests改为request就成功了,成功编译了。
package cc.openhomenine;
import java.util.*;
class Student{
private String name;
private String number;
Student (String name , String number){
this.name = name;
this.number = number;
}
@Override
public String toString(){
return String.format("(%s,%s)", name,number);
}
}
public class Students {
public static void main(String[] args){
Set students = new HashSet();
students.add(new Student("Justin","B835031"));
students.add(new Student("Monica","B835032"));
students.add(new Student("Justin","B835031"));
System.out.println(students);//这里
}
}
这个代码,书上最后一行代码为System.out.println(set);但是却编译不通过显示错误
但是将set改为students就编译通过,且结果与书上相同。
本周代码托管截图
其他(感悟、思考等,可选)
学习java也有一段时间了,在娄老师的督促下,写博客渐渐也从任务变成了习惯,每周按时看书,准时完成博客学习内容,虽然可能就像娄老师上课说的,每个人肯定会有所差别,对于编程的领悟也不同,以至于每个人的学习程度,优良中差也不同。但是我也在尽我最大的努力去学,现在的电子水平越来越高。类似于博客这种电子化的作业也会有很多方面来源的复制,不能仅仅凭借博客的好坏来判断自己的学习还坏,但是我觉得我自己虽然学习java不是很优秀,但是我自己知道我在很努力学,坚持总是会有进步的。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 200/200 | 2/2 | 20/20 | |
第二周 | 300/500 | 2/4 | 18/38 | |
第三周 | 500/1000 | 3/7 | 22/60 | |
第四周 | 300/1300 | 2/9 | 30/90 |