20145212 《Java程序设计》第6周学习总结
20145212 《Java程序设计》第6周学习总结
学习内容总结
第十章
1.Java将输入/输出抽象化为串流。读取数据对象成为输入流,能向其写入的对象叫输出流。
我从网上找到了一个可以更好梳理结构关系的图:
2.inputstream类和outputstream类都为抽象类,不能创建对象,可以通过子类来实例化。
Inputstream类中的常用方法:
public abstract int read( )//读取一个byte的数据,返回值是高位补0的int类型值
public int read(byte b[ ])//读取b.length个字节的数据放到b数组中,返回值是读取的字节数
public int read(byte b[ ], int off, int len)//从输入流中最多读取len个字节的数据,存放到偏移量为off的b数组中
public int available( )//返回输入流中可以读取的字节数
public long skip(long n)//忽略输入流中的n个字节,返回值是实际忽略的字节数, 跳过一些字节来读取
public int close( ) //我们在使用完后,必须对我们打开的流进行关闭
OutputStream类中的常用方法:
public void write(byte b[ ])//将参数b中的字节写到输出流
public void write(byte b[ ], int off, int len) //将参数b的从偏移量off开始的len个字节写到输出流
public abstract void write(int b) //先将int转换为byte类型,把低字节写入到输出流中
public void flush( ) //将数据缓冲区中数据全部输出,并清空缓冲区
public void close( ) //关闭输出流并释放与流相关的系统资源
3.FileInputStream类
FileInputStream类是InputStream类的子类,用来处理以文件作为数据输入源的数据流。
使用方法如下:
//方式1
File fin=new File("d:/abc.txt");
FileInputStream in=new FileInputStream(fin);
//方式2
FileInputStream in=new FileInputStream("d: /abc.txt");
//方式3
构造函数将 FileDescriptor()对象作为其参数
FileDescriptor() fd=new FileDescriptor();
FileInputStream f2=new FileInputStream(fd);
4.从一个流构造另一个流
为InputStream和OutputStream定义decorator类接口的类,分别是FilterInputStream和FilterOutputStream。
FilterInputStream的种类:
DataInputStream与DataOutputStream配合使用,就能以一种"可携带的方式(portable fashion)"从流里读取primitives了。(int,char,long等)
BufferedInputStream用来解决"每次要用数据的时候都要进行物理读取"的问题。
LineNumberInputStream跟踪输入流的行号;有getLineNumber( )和setLineNumber(int)方法。
PushbackInputStream有一个"弹压单字节"的缓冲区(has a one byte push-back buffer),能把最后读到的那个字节压回去。
FilterOutputStream的种类:
DataOutputStream,与DataInputStream配合使用。
PrintStream负责生成带格式的输出(formatted output)。DataOutputStrem负责数据的存储,而PrintStream负责数据的显示。
BufferedOutputStream解决"每次往流里写数据,都要进行物理操作"的问题。就是"用缓冲区"。用flush( )清空缓冲区。
5.字符流的读取和写入:
java.io.Reader和 java.io.InputStream 组成了 Java 输入类。
Reader 用于读入16位字符,也就是 Unicode 编码的字符,InputStream 用于读入 ASCII 字符和二进制数据。
Reader体系结构如下:
6.FileReader
FileReader主要用来读取字符文件,使用缺省的字符编码,有三种构造函数:
//将文件名作为字符串
FileReader f=new FileReader(“c:/temp.txt”);
//构造函数将File对象作为其参数。
File f=new file(“c:/temp.txt”);
FileReader f1=new FileReader(f);
//构造函数将FileDescriptor对象作为参数
FileDescriptor() fd=new FileDescriptor();
FileReader f2=new FileReader(fd);
7.Writer类体系结构如下:
8.DataInputStream类对象可以读取各种类型的数据;DataOutputStream类对象可以写各种类型的数据,创建这两类对象时,必须使新建立的对象指向构造函数中的参数对象。
例:
FileInputStream in=new FileInputStream("d:/abc.txt");
DataInputStream din=new DataInputStream(in);
第十一章
1.线程与并行程序代码实例:
final List list; // 某些长的未排序的对象列表;已在其他地方初始化
/** 用来在后台对List排序的Thread类*/
class BackgroundSorter extends Thread {
List l;
public BackgroundSorter(List l) { this.l = l; } // 构造函数
public void run() { Collections.sort(l); } // 线程主体
}
// 创建BackgroundSorter线程
Thread sorter = new BackgroundSorter(list);// 开始运行;在原来的线程继续执行接下来// 的语句时,新的线程会执行run() methodsorter.start();
// 这是另一个定义类似线程的方法
Thread t = new Thread(new Runnable() { // 创建一个新的线程
public void run() { Collections.sort(list); } // 为对象列表排序
t.start(); // 开始运行
}
2.我们可以对线程中未被捕获的异常安装自定义的处理程序:
// 此线程正好抛出一个异常
Thread t = new Thread() {
public void run() {
throw new UnsupportedOperationException();
}
}
// 给线程一个名称以帮助调试
t.setName("My Broken Thread");
// 这是针对错误的处理程序
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
System.err.printf("Exception in thread %d '%s':" + "%s at line %d of %s%n",
t.getId(), // 线程id
t.getName(), // 线程名称
e.toString(), // 异常名称与信息
e.getStackTrace()[0].getLineNumber(), // 行号
e.getStackTrace()[0].getFileName()); // 文件名
}
}
3.让线程在特定的一段时间休眠或停止运行,可以用静态的Thread.sleep() method做到,或者在Java中可以用TimeUnit类的列举常量的实用程序method:
import static java.util.concurrent.TimeUnit.SECONDS; // 实用程序类
public class Clock extends Thread {
// 此字段是易变的,因为两个不同的线程会访问它
volatile boolean keepRunning = true;
public Clock() { // 构造函数
setDaemon(true); //daemon线程:解释器可以在它运行时跳出
}
public void run() { // 线程主体
while(keepRunning) { // 此线程会运行直到被要求停止为止
long now = System.currentTimeMillis();// 取得当前时间
System.out.printf("%tr%n", now);// 输出当前时间
try { Thread.sleep(1000); }// 等待1000毫秒
catch (InterruptedException e) { return; }// 在中断时结束
}
}
4.线程完成run()方法,就会进入Dead,进入(或者已经调用过start()方法)的线程,不可以再次调用start()方法,否则会抛出错误。
5.如果要停止线程,最好自行操作,让程序走完应有流程,而不是调用syop()方法
6.wait()、notify()与notifyAll()是由Object类别所提供的方法
7.当物件的wait()方法被调用,目前的线程会被放入对象的等待池中,线程归还对象的锁定
关于这一点的代码例子如下:
public synchronized void setProduct(int product) {
if(this.product != -1) {
try { //目前店员没有空间收产品,请稍候!
wait();
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
this.product = product;
System.out.printf("生产者设定(%d)%n", this.product); //通知等待区中的一个消费者可以继续工作了
notify();
}
public synchronized int getProduct() {
if(this.product == -1) {
try { //缺货了,请稍候!
wait(); }
catch(InterruptedException e) {
e.printStackTrace();
}
}
int p = this.product;
System.out.printf("消费者取走(%d)%n", this.product);
this.product = -1; //取走产品,-1表示目前店员手上无产品
//通知等待区中的一个生产者可以继续工作了
notify();
return p;
}
本周代码托管截图
其他
随着学习越来越深入,我发现由于我之前的学习很不踏实,很多知识点被我忽略掉或者忘记了,导致我不能很好地理解后面书上所说的内容,有时候学习新知识的时候就会返回前面看基础,这样虽然有些慢但是对之前的内容学习也算是一种复习或者说巩固吧。
这一章的JAVA让我感觉到API的使用在Java的学习中非常重要,由于之前的学习中没有这么练习这方面的内容,对于很多类的用法也是模模糊糊,只能照搬书上的代码使用,学习这章之后,我才发现JAVA远比我想象的要复杂深奥的多,一个知识环节往往套着一堆更深入的知识,稍微一百度,就能牵扯到很多新的概念。对于我来说,JAVA学习的道路还很长,虽然目前我还是不能完全的消化掉书上的内容,但是我会努力通过实践和查阅更深入的资料将疑点一一解决。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 200/200 | 2/2 | 10/10 | |
第二周 | 300/500 | 1/3 | 16/26 | |
第三周 | 300/800 | 1/4 | 18/44 | |
第四周 | 300/1100 | 1/5 | 18/62 | |
第五周 | 250/1350 | 1/6 | 14/76 | |
第五周 | 400/1750 | 2/8 | 14/90 |