I/O 基础
Java 的 I/O 操作通过流来实现。流是对输入、输出数据的抽象,每个流都和一个具体的物理实体关联,比如在输入中,流可以和键盘、磁盘文件或者网络输入等关联,虽然每个物理实体不同,但是流可以以同样的方式进行处理。
Java 定义了字节流和字符流。字节流处理的对象是二进制数据,以字节的方式处理。字符流处理的对象是字符,字符编码为 Unicode,方便国际化。最底层而言,所有的 I/O 操作都是面向字节的。
字节流定义了两个类层次,最高层分别为抽象类 InputStream、OutputStream,这两个类都有若干个具体的子类处理不同情况的 I/O 操作。这两个抽象类分别定义了 read()
和 write()
方法用于读写字节数据,具体实现由子类完成。
字符流与字节流类似,抽象类为 Reader 和 Writer,分别定义了 read()
和 write()
方法用于读写字符数据。
java.lang 包中定义了 System 类,这个类中定义了 3 个流类型静态变量,分别为 in、out、err。使用 public static final 修饰,不需要实例化 System 类就可以使用。in、out、err 三者分别默认表示标准输入流键盘、标准输出流控制台、标准错误流控制台。可以自行更改,表示不同的设备。in 的类型为 InputStream,out、err 的类型为 PrintStream,三者都是字节流。
读控制台输入
从控制台读取即从 System.in 读取。为得到和控制台绑定的基于字符的流,需要将 System.in 包装成表示字符流的类。
// 将一个字符输入流转换成有缓存的字符输入流
BufferedReader(Reader);
// 将一个字节流转换成字符流
InputStreamReader(InputStream);
// 将控制台输入字节流转成有缓存的字符输入流
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
使用 int read()
方法可以从 BufferedReader 对象中每次读取一个字符并返回该字符表示的整数,如果到达了流的末尾,则返回 -1。
System.in 是行缓冲,在没有按换行键之前输入不会传递给程序。
使用 BufferedReader 类的 String readLine()
方法每次读取一行作为字符串返回。
写控制台输出
PrintStream 类的 void write(int)
方法写出的字节个数由参数指定,参数类型虽然为 int,但只有低 8 位有效。
PrintWriter 类
控制台输出使用 PrintWriter 流。PrintWriter(OutputStream, boolean)
构造器中第一个参数为输出流对象,第二个参数如果为 true,则自动刷新;否则,不自动刷新。
// 这里 pw 相当于 System.out,只不过类型是基于字符流的,优点是易于国际化
PrintWriter pw = new PrintWriter(System.out, true);
pw.println("string");
读写文件
和文件相关的常见类为 FileInputStream 和 FileOutputStream,两者都是与文件关联的字节流。 FileInputStream(String)
和 FileOutputStream(String)
构造器的参数为想要打开的文件名。对于输入流,文件不存在,则抛出异常;对于输出流,文件不存在或者打不开,抛出异常,当文件打开时,之前同名的文件被销毁。
使用完文件后,使用 close()
方法关闭文件,释放分配给文件的系统资源。这个方法定义在 AutoCloseable 接口中。一般在 finally 子句中关闭文件。
从 JDK7 开始,try-with-resources 语句可以在文件不再使用时自动关闭。
每次使用 int read()
读取文件时,读取文件的一个字节并返回这个字节表示的整数,当到文件末尾时返回 -1。void write(int)
写文件与之类似,每次写入一个字节。
自动关闭文件
try (resource) {
// use
}
JDK7 开始,提供了 try-with-resoucres 块。resouce 是一条用于定义和初始化要用的资源的语句,当资源在 try 块中使用完毕后,会自动释放该资源。resouce 也可以是之前定义和初始化的变量,此时该变量必须由 final 修饰才能在 try 块中使用。
try-with-resoucres 块仅能用于实现了 AutoCloseable 接口的类,该接口定义了一个 close()
方法,流类都实现了该接口。该块中 resouce 的定义隐式被 final 修饰,作用域为整个 try 块。
从 JDK10 开始,可以在 try-with-resoucres 块中使用局部变量类型推导。
try (var fin = new FileInputStream("name.dat"))
try 语句中,可以定义多个变量,每个用分号相隔。当该块中产生异常时,很容易引发另一个异常,第二个异常会和第一个异常关联,并被抑制,可以使用 getSuppressed()
方法获取。
transient 和 volatile 修饰符
transient 修饰的变量表示其内容不需要持久保存,在序列化时忽略该变量。
// 当一个 T 类型对象保存到持久化存储介质(比如磁盘)时,
// 属性 a 不会写入,b 会写入其中。
class T {
transient int a;
int b;
}
volatile 告知编译器它修饰的变量内容可能会被其他线程修改,变量的内容对其他线程可见,一般发生在多线程共享变量的情形。
instanceof
子类可以转换成超类,反之不然。instanceof 语法为:
objectRef instanceof type
如果引用的对象类型为 type 或者可以转换成 type,则返回 true,否则返回 false。
strictfp
strictfp 修饰的类、接口或方法中浮点数的计算使用老模型,在计算时中间结果发生截断,而使用新模型中间结果不会发生截断。
本地方法
native
用于定义本地码方法,该方法是用非 Java 语言编写的。定义之后可以在 Java 程序中调用,这个机制称为 Java Native Interface(JNI)。例如:
// 不需要方法体
public native int m();
assert
assert 用于开发过程中,判断条件是否发生,条件发生,则无事发生;否则,抛出 AssertionError 错误。
断言的一般形式为:
// cond 是一个计算结果为 boolean 类型的表达式
assert cond
// exp 是传递给 AssertionError 构造器的值,当错误发生时,显示该值。
// exp 一般是断言失败时,想要显示的信息
assert cond:exp
assert n > 0 : "n less than or equal to 0"
使用断言加上 -ea,例如 java -ea programName
。
断言中不能依赖任何正常流代码,否则,当断言被禁用时,可能产生问题。
使用 -ea:Name
/-da:Name
可以分别启用、禁用特定范围的断言,Name 可以是类名、包名。
静态导入
静态导入会导入类或接口中的静态成员。使用时直接使用静态成员名称,不需要加上类名或接口名限定。
import static pkg.typeName.staticMember;
导入特定静态成员。
import static pkg.typeNname.*;
导入所有静态成员。
需要多次使用某个静态成员时,使用静态导入比较方便。但是,仅少数使用几次的静态成员没必要使用静态导入,因为可能造成属于不同命名空间具有相同名称的静态成员引入同一个文件造成命名冲突。
通过 this() 调用重载构造器
this(argList)
在构造器第一行调用 this,根据传入的参数类型和个数调用匹配的构造器。可以用于减少重复代码,能减少加载类的时间。
在构造器内调用 this 会有一定的开销,当调用这种类型的构造器创建大量对象时,会带来很大的开销。需要权衡减少加载类的时间和创建对象的开销。
构造器内的初始化代码很少时,是否使用 this 差别不大,因为字节码将 this 的初始化内容添加到当前文件中,当初始化代码少时,能减少的类加载时间很少。对于有大量初始化代码的构造器,this 的使用能明显减少类加载时间。
不能使用类实例调用 this()
方法;不能在同一构造器中同时使用 super()
和 this()
方法,因为这两个方法都必须是构造器的第一条语句。
紧凑 API Profiles
JDK8 将 API 库划分成了多个子集,称为紧凑 profiles,分别称为 compact1, compact2, compact3,其中 compact3 包含 compact2, compact2 包含 compact1。使用紧凑 profiles 的好处是当某个应用只需要使用 API 库的一部分功能时,使用 compact 可以减少代码库大小,减少加载程序的时间。
参考
[1] Herbert Schildt, Java The Complete Reference 11th, 2019.
标签:JTCR,字节,字符,静态,try,Try,文件,使用,Resources From: https://www.cnblogs.com/xdreamc/p/16393711.html