本文最后更新于:2021年6月26日 下午
概览 :Java常用类:Object、包装类、String类、File类、IO流。
预警!仅用于本人快速自学,不过欢迎指正。
Scanner java.util.Scanner
。
创建对象:Scanner s = new Scanner(System.in);
获取输入:next()
方法以及nextLine()
方法,同时与hasNext()
以及hasNextLine()
进行配合。
1 2 3 4 5 6 7 8 9 10 11 12 import java.util.Scanner;public class TestScanner { public static void main (String[] args) { Scanner scan = new Scanner(System.in); String s = null ; while (scan.hasNextLine()){ s = scan.nextLine(); System.out.println(s); } } }
next与nextLine的区别 next():
1、一定要读取到有效字符后才可以结束输入。
2、对输入有效字符之前遇到的空白,next() 方法会自动将其去掉 。
3、只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
4、next() 不能得到带有空格 的字符串。
nextLine():
1、以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符。
2、可以获得空白。
读取数字
读取int型:hasNextInt()
,然后nextInt()
读取double型:hasNextDouble()
然后nextDouble()
。
Object类 理论上所有的类都直接或者间接继承java.Lang.Object
类。
主要方法:
toString()
getClass()
equals()
clone()
finalize()
toString() 1 2 3 public String toString () { return getClass().getName() + "@" + Integer.toHexString(hashCode()); }
类名 + @
+ 哈希码的无符号16进制
建议自定义类重写此方法
getClass() 1 public final native Class<?> getClass();
返回运行时类型
final表示不能够重写,一般与后接getName()
方法。
equals() 1 2 3 public boolean equals (Object obj) { return (this == obj); }
判断obj与本身对象是不是指向了同一个对象(同一块内存)。
若希望不比较内存而比较内容的话,最好重写equals
方法,例如String类。
clone() 1 protected native Object clone () throws CloneNotSupportedException ;
复制对象。
即先分配一个和源对象大小相同的空间,在这个空间中创建出一个新的对象。
使用new创建一个对象
使用clone复制一个对象
作用:用于拷贝出一个新的对象,对新对象的修改不会影响原来的对象!即普通的A a = b
,这样两个引用指向了同一块内存,修改对相互之间都会产生影响。而clone可以满足这样的需求,提供精确拷贝,生成一个新的对象。
Shallow Clone与Deep Clone 浅拷贝:简单的执行域对域的拷贝,对于一个Reference变量,简单的拷贝之后会由两个Reference指向了同样的内存。
深拷贝:对Reference变量进行处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Salary implements Cloneable { private double sal; private double reword; @Override protected Object clone () throws CloneNotSupportedException { return super .clone(); } }class Employee implements Cloneable { private String name; private Salary salary; @Override protected Object clone () throws CloneNotSupportedException { Employee cloned = (Employee) super .clone(); cloned.salary = (Salary) salary.clone(); return cloned; } }
Object中clone()
是被声明为protected
。
调用Clone()方法的对象所属的类(Class)必须implements Clonable
接口,否则在调用Clone方法的时候会抛出CloneNotSupportedException
finalize() 1 protected void finalize () throws Throwable { }
用于释放资源。
工作原理:一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用其finalize()方法。并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。
用途:无论对象是如何创建的,垃圾回收器都会负责释放对象占据的所有内存。
hashCode() 1 public native int hashCode () ;
返回对象的哈希值。
用于哈希查找,可减少在查找中使用equals的次数,重写equals方法一般都要重写hashCode方法。
一般必须满足obj1.equals(obj2)==true
。可以推出obj1.hashCode() == obj2.hashCode()
,但是hashCode相等不一定就满足equals。不过为了提高效率,应该尽量使上面两个条件接近等价。
wait() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public final native void wait (long timeout) throws InterruptedException ;public final void wait (long timeout, int nanos) throws InterruptedException { if (timeout < 0 ) { throw new IllegalArgumentException("timeout value is negative" ); } if (nanos < 0 || nanos > 999999 ) { throw new IllegalArgumentException( "nanosecond timeout value out of range" ); } if (nanos > 0 ) { timeout++; } wait(timeout); }public final void wait () throws InterruptedException { wait(0 ); }
wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。
wait()方法一直等待,直到获得锁或者被中断。wait(long timeout)设定一个超时间隔,如果在规定时间内没有获得锁就返回。
调用该方法后当前线程进入睡眠状态,直到以下事件发生。
(1)其他线程调用了该对象的notify方法。 (2)其他线程调用了该对象的notifyAll方法。 (3)其他线程调用了interrupt中断该线程。 (4)时间间隔到了。
此时该线程就可以被调度了,如果是被中断的话就抛出一个InterruptedException异常
notify() 1 2 public final native void notify () ;public final native void notifyAll () ;
唤醒在该对象上等待的某个线程。
包装类 虽然 Java 语言是典型的面向对象编程语言,但其中的八种基本数据类型并不支持面向对象编程,基本类型的数据不具备“对象”的特性——不携带属性、没有方法可调用。 沿用它们只是为了迎合人类根深蒂固的习惯,并的确能简单、有效地进行常规数据处理。
这种借助于非面向对象技术的做法有时也会带来不便,比如引用类型数据均继承了 Object 类的特性,要转换为 String 类型(经常有这种需要)时只要简单调用 Object 类中定义的toString()即可,而基本数据类型转换为 String 类型则要麻烦得多。为解决此类问题 ,Java为每种基本数据类型分别设计了对应的类,称之为包装类(Wrapper Classes),也有教材称为外覆类或数据类型类。
基本数据类型
包装类
byte
Byte
short
Short
int
Integer
long
Long
char
Character
float
Float
double
Double
boolean
Boolean
所有的包装类都是抽象类Number的子类。
包装类的对象可以封装对象基本类型的数据,并提供了一些有用的方法。
包装类对象一经创建,其内容即所封装的基本类型数据值不可改变。
装箱与拆箱
装箱 :基本来向装箱包装类
拆箱 :包装类转向基本类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class TestWrapper { public static void main (String[] args) { int m = 10 ; Integer inte = new Integer(m); System.out.println(inte.intValue()); int n= inte.intValue(); Integer inte2 = new Integer(10 ); System.out.println("inte == inte2 ? " + inte.equals(inte2)); int a = 20 ; Integer num1 = a; System.out.println("num1 " + num1.toString()); int a1 = num1; System.out.println("a1 " + a1); Integer num2 = 20 ; System.out.println("num1 == num2 ? " + num1.equals(num2)); } }
数字与字符串的转换
字符串转数字:parseInt(String s,int radix)
,radix指明进制,默认十进制。
数字转字符串:toString()
或者"" + s
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public class ParseStr { public static void main (String[] args) { String [] str = {"123" ,"123a" ,"a123" ,"abc" }; for (String tmp :str){ try { int m = Integer.parseInt(tmp); System.out.println(tmp + "可以转为数字: " + m); }catch (Exception e){ System.out.println(tmp + "不可转为数字!" ); } } Integer inte = 100 ; System.out.println("inte: " + inte.toString()); System.out.println("inte: " + inte); } }123 可以转为数字: 123 123a不可转为数字! a123不可转为数字! abc不可转为数字! inte: 100 inte: 100
Math类 1 2 3 4 5 6 7 8 9 10 11 12 Math.PI 圆周率 Math.E 常量E Math.abs 绝对值 Math.ceil 获取不小于某数的最大整数 Math.floor 获取不大于某数的最大整数 Math.max 求两数中最大值 Math.min 求两数中最小值 Math.sqrt 求开方 Math.pow 求某次方 Math.exp 求e的某次方 Math.log 求自然对数 Math.random 返回0 -1 之间的一个double 随机数
Random类 待续
时间日期类 待续
String类
代表字符串,Java中的所有字符串字面量都是此类的实例实现。
字符串是常量,它们的值创建之后不能更改。
字符串缓冲区支持可变的字符串。
1 2 3 4 5 6 7 private final char value[];private int hash; private final int offset;private final int count;private static final long serialVersionUID = -6849794470754667710L ;private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0 ];
构造方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 String() String(byte [] bytes) String(byte [] bytes, Charset charset) String(byte [] bytes, int offset, int length) String(byte [] bytes, int offset, int length, Charset charset) String(byte [] bytes, int offset, int length, String charsetName) String(byte [] bytes, String charsetName) String(char [] value) String(char [] value, int offset, int count) String(int [] codePoints, int offset, int count) String(String original) 的字符串是该参数字符串的副本。 String(StringBuffer buffer) String(StringBuilder builder)
创建字符串对象 直接赋值创建,位于方法去的常量池 中。
通过构造方法,位于堆内存之中。
1 String str = new String("hello" );
比较
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class TestStr { public static void main (String[] args) { String str1 = "hello" ; String str2 = str1; System.out.println(str1 == str2); System.out.println(str1.equals(str2)); String str3 = new String("hello" ); String str4 = str3; System.out.println(str3 == str4); System.out.println(str3.equals(str4)); System.out.println(str1 == str3); System.out.println(str1.equals(str3)); } }
字符串常量池
如果采用直接赋值的方式进行对象的实例化String s1 = "hi"
,则会将匿名对象"hi"
放入对象池 之中,每当下一次对不同的对象进行直接赋值的时候会直接利用池中原有的匿名对象。
当然也可以手动入池
1 2 3 String s1 = new String("hi" ).intern(); String s2 = "hi" ; System.out.println(s1 == s2);
字符串两种实例化方法的区别
直接赋值:只开辟一块堆内存空间,并且会自动入池,不会产生垃圾。
构造方法:会开辟两块堆内存空间,其中一块堆内存会变成垃圾被系统回收,而且不能够自动入池,需要手动入池。
String类的常用方法 字符串比较判断
1 2 3 4 boolean equals (Object obj) :比较字符串的内容是否相同boolean equalsIgnoreCase (String str) : 比较字符串的内容是否相同,忽略大小写boolean startsWith (String str) : 判断字符串对象是否以指定的str开头boolean endsWith (String str) : 判断字符串对象是否以指定的str结尾
截取
1 2 3 4 5 6 int length () :获取字符串的长度,其实也就是字符个数char charAt (int index) :获取指定索引处的字符int indexOf (String str) :获取str在字符串对象中第一次出现的索引String substring (int start) :从start开始截取字符串 String substring (int start,int end) :从start开始,到end结束截取字符串。包括start, 不包括end
转换
1 2 3 char [] toCharArray():把字符串转换为字符数组String toLowerCase () :把字符串转换为小写字符串 String toUpperCase () :把字符串转换为大写字符串
分割、去除空格
1 2 去除字符串两端空格:String trim () 按照指定符号分割字符串:String[] split (String str)
StringBuilder StringBuffer StringBuilder 是一个可变的字符序列。它继承于AbstractStringBuilder,实现了CharSequence接口。StringBuffer 也是继承于AbstractStringBuilder的子类;但是,StringBuilder和StringBuffer不同,StringBuilder是非线程安全的,StringBuffer是线程安全的。
insert 1 2 3 4 5 6 7 8 9 10 insert(int offset,Object o); insert(int offset,Object []o,int begin,int len); insert(CharSequence s,int start,int end); StringBuilder sbuild = new StringBuilder(); sbuild.insert(0 ,123 ); sbuild.insert(0 ,new char []{'a' ,'b' ,'c' },0 ,3 ); sbuild.insert(0 ,new StringBuilder("helloworld" ),5 ,10 ); System.out.println(sbuild.toString());
append 1 2 3 4 5 6 7 8 9 10 append(Object o); append(char [],int offset,int len); append(CharSequence s,int begin,int end); StringBuilder sbulids = new StringBuilder(); sbulids.append(123 ); sbulids.append(true ); sbulids.append(new char []{'a' ,'b' ,'c' },0 ,3 ); sbulids.append(new StringBuffer("helloworld" ),5 ,10 ); System.out.println(sbulids.toString());
其他API 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 StringBuilder sbuilder = new StringBuilder("helloworld" ); sbuilder.replace(0 ,5 ,"well" ); System.out.println(sbuilder.toString()); sbuilder.reverse(); System.out.println(sbuilder.toString()); sbuilder.setCharAt(0 ,'A' ); System.out.println(sbuilder.toString()); sbuilder.deleteCharAt(0 ); System.out.println(sbuilder.toString()); sbuilder.delete(0 ,3 ); System.out.println(sbuilder.toString()); String strs = sbuilder.substring(3 ); System.out.println(strs); strs = sbuilder.substring(2 ,5 ); System.out.println(strs); strs = (String)sbuilder.subSequence(2 ,5 ); System.out.println(strs); System.out.println(sbuilder.toString()); System.out.println("从前向后中 e第一次出现的位置" + sbuilder.indexOf("e" )); System.out.println("从索引2开始,w第一次出现的位置" +sbuilder.indexOf("w" ,2 )); System.out.println("从后向前,e第一次出现的位置" + sbuilder.lastIndexOf("e" ));
String StringBuilder StringBuffer
String 字符串常量
StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)
速度:StringBuilder > StringBuffer > String
使用:
如果要操作少量的数据用 = String
单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
多线程操作字符串缓冲区 下操作大量数据 = StringBuffer
File类 java.io.File
类:文件和目录路径名的抽象表示形式。
构造方法:
1 public File (String pathname)
如果pathname是相对路径,则默认的当前路径在系统属性user.dir 中存储。
File的静态属性String separator存储了当前系统的路径分隔符。
访问属性:
1 2 3 4 5 6 7 8 9 10 public boolean isFile () ;public boolean isDiractory () ;public boolean exists () ;public long lastModified () ;public String getName () ;public boolean canRead () ;public boolean canWrite () ;public boolean isHidden () ;public long length () ;public String getPath () ;
创建空文件或者目录:(在File对象所指的文件或者目录不存在的情况下)
1 2 3 4 5 6 public boolean createNewFile () throws IOException ;public boolean delete () ;public boolean mkdir () ; public boolean mkdirs () ;public boolean renameTo (File dest)
实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public class TestJava { public static void main (String[] args) { File f2 = new File("BN.java" ); System.out.println("exist: " + f2.exists()); System.out.println("file: " + f2.isFile()); System.out.println("name: " + f2.getName()); System.out.println("len: " + f2.length()); try { f2.createNewFile(); }catch (IOException e){ e.printStackTrace(); } File dir = new File("Test" ); if ( dir.mkdirs()){ System.out.println("success" ); }else { System.out.println("failed" ); } File newfile = new File("Test" +"/" + f2.getName() ); if (newfile.exists()){ System.out.println("已经存在!" ); }else { if (f2.renameTo(newfile)){ System.out.println("移动成功!" ); }else { System.out.println("移动失败!" ); } } } }
IO流 字节流和字符流
**字节流(8bit)**:最原始的一个流,读出来的数据就是010101这种最底层的数据表示形式,只不过它是按照字节来读的,一个字节(Byte)是8位(bit)读的时候不是一个位一个位的来读,而是一个字节一个字节来读
**字符流(16bit)**:字符流是一个字符一个字符地往外读取数据。一个字符是2个字节。
输入流和输出流 java.io
包中提供的流类型都分别继承自以下四种抽象流
输入流 :InputStream(字节流),Reader(字符流)
输出流 :OutPutStream(字节流),Writer(字符流)
输入和输出是站在程序的角度 ,从文件中读数据,这叫做输入!
节点流和处理流
节点流 :可以从一个特定的数据源(节点)读取数据,例如文件、内存
处理流 :是建立在已经存在的流(节点流或者处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。
节点流类型
类型
字符流
字节流
File
FileReader、FileWriter
FileInputStream、FileOutputStream
Memory Array
CharArrayReader、CharArrayWriter
ByteArrayInputStream、ByteArrayOutputStream
Memory String
StringReader、StringWriter
-
Pipe
PipeReader、PipeWriter
PipeInputStream、PipeOutputStream
处理流类型
处理类型
字符流
字节流
Buffering
BufferedReader、BufferedWriter
BufferedInputStream、BufferedOutputStream
Filtering
FilterReader、FilterWriter
FilterInputStream、FilterInputStream
Converting between bytes and chaacter
InputStreamReader、 OutputStreamWriter
-
Object Serialization
-
ObjectInputStream、 ObjectOutputStream
Data conversion
-
DataInputStream、 DataOutputStream
Counting
LineNumberReader
LineNumberInputStream
Peeking ahead
PusbackReader
PushbackInputStream
Printing
PrintWriter
PrintStream
基本方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 int read () throws IOExceptionint read (byte [] buffer) throws IOExceptionint read (byte [] buffer,int offset,int length) throws IOExceptionvoid close () throws IOExceptionlong skip (long n) throws IOException
read()
一个一个字节读
read(byte[] buffer)
则是先使用缓冲区再读。
案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public class TestInput { public static void main (String[] args) { FileInputStream in = null ; try { in = new FileInputStream("./src/General/ParseStr.java" ); }catch (FileNotFoundException e){ System.out.println("file not found" ); System.exit(-1 ); } int ret = 0 ; long num = 0 ; try { while ((ret = in.read()) != -1 ) { System.out.println((char ) ret); num++; } in.close(); System.out.println("all byte : " + num); }catch (IOException e){ System.out.println("read error!" ); } } }
一个字节一个字节的读取,对于中文就会产生乱码,这是应当采用字符流。
OutputStream 输出流
常用方法:
1 2 3 4 5 6 7 8 9 10 void write (int b) throws IOExceptionvoid write (byte [] b) throws IOExceptionvoid write (byte [] b,int off,int len) throws IOExceptionvoid close () throws IOExceptionvoid flush () throws IOException
案例:文件拷贝
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 package JavaIO;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;public class TestOutput { public static void main (String[] args) { FileInputStream in = null ; FileOutputStream out = null ; try { in = new FileInputStream("./src/General/ParseStr.java" ); out = new FileOutputStream("./src/General/ParseStrNew.java" ); }catch (FileNotFoundException e){ System.out.println("File not found" ); System.exit(-1 ); } int b = 0 ; try { while ( (b = in.read()) != -1 ){ out.write(b); } in.close(); out.close(); }catch (IOException e){ System.out.println("File copy failed" ); System.exit(-1 ); } } }
Reader
1 2 3 4 5 6 7 8 9 10 11 12 13 14 int read () throws IOExceptionint read (byte [] buffer) throws IOExceptionint read (byte [] buffer,int offset,int length) throws IOExceptionvoid close () throws IOExceptionlong skip (long n) throws IOException
Writer流
1 2 3 4 5 6 7 8 9 10 void write (int b) throws IOExceptionvoid write (byte [] b) throws IOExceptionvoid write (byte [] b,int off,int len) throws IOExceptionvoid close () throws IOExceptionvoid flush () throws IOException
缓冲流 Buffering 缓冲流要套在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率。
1 2 3 4 5 6 7 8 BufferedReader(Reader in); BufferedReader(Reader in,int sz); BufferedWriter(Writer out); BufferedWriter(Writer out,int sz); BufferedInputStream(InputStream in); BufferedInputStream(InputStream in,int sz); BufferedOutputStream(OutputStream in); BufferedOutputStream(OutputStream in,int sz);
案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package JavaIO;import java.io.*;public class TestBufferRead { public static void main (String[] args) { try { BufferedWriter bw = new BufferedWriter( new FileWriter("./Test/hi.txt" )); for (int i = 0 ;i<100 ;i++){ bw.write((char )i); bw.newLine(); } bw.flush(); BufferedReader br = new BufferedReader(new FileReader("./Test/hi.txt" )); String s = null ; while ( (s = br.readLine()) != null ){ System.out.println(s); } br.close(); bw.close(); }catch (Exception e){ e.printStackTrace(); } } }
转换流
InputStreamReader
和OutputStreamWriter
用于字节数据到字符数据之间的转换 。
InputStreamReader
需要InputStream
套接
OutputStreamWriter
需要OutputStream
套接
转换流在构造时可以指定其编码集合。
1 InputStreamReader isr = new InputStreamReader(System.in,"ISO8859-1" );
System.in
是一个标准的输入流,用来接收从键盘输入的数据。
OutputStream
是字节流,Writer
是字符流, OutputStreamWriter
就是把OutputStream
转换成Writer
。把OutputStream
转换成Writer
之后就可以 一个字符一个字符地通过管道写入数据了。
实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class TestTransIO { public static void main (String[] args) { try { OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("./Test/he.txt" )); osw.write("ABCDEFGHIJKLMN" ); System.out.println("当前编码" + osw.getEncoding()); osw = new OutputStreamWriter(new FileOutputStream("./Test/he.txt" ,true ),"ISO8859_1" ); osw.write("ABCDEFGHIJKLMN" ); System.out.println("当前编码" + osw.getEncoding()); osw.close(); }catch (Exception e){ e.printStackTrace(); } } } 当前编码UTF8 当前编码ISO8859_1
使用了转换流之后就可以以字符串的形式写入文件中,提高了写入的速度,也减少了对硬盘的访问次数。
而若是使用FileOutputStream
来写入,就只能是一个字节一个字节的尽心写入了。
数据流
DataInputStream 和 DataOutputStream 分别继承自InputStream 和 OutputStream , 它属于处理流,需要分别“套接”在InputStream 和 OutputStream类型的节点流上。
DataInputStream 和 DataOutputStream 提供了可以存取与机器无关的Java原始类型数据(int,double等)的方法。
1 2 DataInputStream(InputStream in); DataOutputStream(OutputStream out);
案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class TestDataIO { public static void main (String[] args) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); try { dos.writeDouble(Math.PI); dos.writeInt(123 ); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); DataInputStream dis = new DataInputStream(bais); System.out.println(dis.readDouble()); System.out.println(dis.readInt()); }catch (Exception e){ e.printStackTrace(); } } }
通过bais这个流往外读取数据的时候,是一个字节一个字节地往外读取的,因此读出来的数据无法判断是字符串还是其他类型的值,因此要在它的外面再套一个流,通过dataInputStream把读出来的数据转换就可以判断了。
打印流
PrintWriter 和 PrintStream 都属于输出流,分别针对与字符和字节
PrintWriter 和 PrintStream 提供了重载的print
Println方法用于多种数据类型的输出
PrintWriter和PrintStream的输出操作不会抛出异常,用户通过检测错误状态获取错误信息
PrintWriter 和 PrintStream有自动flush功能
1 2 3 4 5 6 PrintWriter(Writer out); PrintWriter(Writer out,boolean autoFlush); PrintWriter(OutputStream out); PrintWriter(OutputStream out,boolean autoFlush); PrintStream(OutputStream out); PrintStream(OutputStream out,boolean autoFlush);
案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class TestPrintIO { public static void main (String[] args) { PrintStream ps = null ; try { FileOutputStream fos = new FileOutputStream("./Test/log.txt" ); ps = new PrintStream(fos); if (ps != null ){ System.setOut(ps); } for (int c = 0 ;c<100 ;c++){ System.out.print(c + " " ); } }catch (Exception e){ e.printStackTrace(); } } }
对象流
直接将Object写入或者读出
transient
关键字,表示透明
,用它来修饰的成员变量在序列化的时候不予考虑,也就是当成不存在。
凡是要将一个类的对象序列化成一个字节流就必须实现Serializable接口
Serializable接口中没有定义方法,Serializable接口是一个标记性接口,用来给类作标记, 只是起到一个标记作用。
这个标记是给编译器看的,编译器看到这个标记之后就可以知道这个类可以被序列化 如果想把某个类的对象序列化,就必须得实现Serializable接口
直接实现Serializable接口的类是JDK自动把这个类的对象序列化,而如果实现public interface Externalizable extends Serializable
的类则可以自己控制对象的序列化,建议能让JDK自己控制序列化的就不要让自己去控制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Cat implements Serializable { int i = 10 ; double j = 3.14 ; char k = 'a' ; transient int m = 1 ; }public class TestObjectIO { public static void main (String[] args) { Cat cat = new Cat(); cat.i = 100 ; try { FileOutputStream fos = new FileOutputStream("./Test/Cat.txt" ); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(cat); oos.flush(); oos.close(); fos.close(); FileInputStream fis = new FileInputStream("./Test/Cat.txt" ); ObjectInputStream ois = new ObjectInputStream(fis); Cat tmp = (Cat)ois.readObject(); System.out.println(tmp.i + " " + tmp.j + " " + tmp.k + " " + tmp.m); ois.close(); fis.close(); }catch (Exception e){ e.printStackTrace(); } } }
System.in System.out
System.in
是 InputStream
类型,字节流,程序使用它可读取键盘输入的数据;
System.out
是 PrintStream
类型(是OutputStream
的子类),字节流,程序使用它可将数据输出到显示屏上。