1.静态导入java
做用:简化书写
静态导入能够做用一个类的全部静态成员
静态导入格式:import static 包名.类名
静态导入要注意的事项:
若是静态导入的成员与本类的成员存在同名的状况下,那么默认使用本类的静态成员,若是须要制定使用静态导入的成员,那么须要在静态成员前面加上类名。spring
2.加强for循环
加强for循环的做用,简化迭代器的书写格式
加强for循环的适用范围:若是是实现了Iterabl接口的对象或者是数组对象,,均可以使用加强for循环
加强for循环的格式:
for(变量类型 变量名:遍历的目标){
}
加强for循环要注意的事项:
1.加强for循环的底层仍是使用了迭代器遍历,只不过不须要咱们去获取这个迭代器,因此在使用加强for循环变量元素的过程当中不许使用集合对象对集合的元素个数进行修改。
2.迭代器遍历元素与加强for循环遍历元素的区别:使用迭代器遍历集合的元素时能够删除集合的元素,而加强for循环遍历集合的元素时,不能调用迭代器的remove方法删除素。
3.普通for循环与加强for循环的区别:普通for循环能够没有遍历的目标,而加强for循环必定要有遍历的目标。
4.Map集合没有实现Iterable接口,因此map集合不能直接使用加强for循环,若是须要使用加强for循环,须要借助与collection的集合遍历。凡是一个数组对象,内存地址都是以中括号开头的。数组
3.可变参数
可变参数的格式是:
数据类型...变量名
可变参数要注意的细节:
1.若是一个函数的形参使用上了可变参数以后,那么调用该方法的时候能够传递参数也能够不传递参数。
2.可变参数其实是一个数组对象。
3.可变参数必须位于形参中的最后一个。
4.一个函数最多只能有一个可变参数,由于可变参数要位于形参中的最后一个的位置
4.自动装箱和拆箱
自动装箱:自动把java中的基本数据类型转换成对象类型的数据。
java是面向对象的语言,任何事物均可以使用类进行描述,sun就使用了一些类
自动拆箱:把引用类型的数据转换成基本类型的数据。
描述java中八种基本数据类型标准。
基本数据类型 包装类型
byte Byte
short Short
int Integer
long Long
float Float
double Double
boolean Boolean
char Character
小知识点:Integer类内部维护了缓冲数组,该缓冲数组存储了-127~128这些数据在一个数组中,若是你获取的数据是落入到这个范围以内的,那么就直接从该缓冲区中获取对应的数据。
5.枚举值jvm
问题:某些方法所接收的数据必须是在固定范围以内的。ide
解决方案:自定义一个类,而后私有化构造函数,在自定义类中建立本类的对象来解决。函数
JDK1.5对以上问题提出了新的解决方案,就是使用枚举类解决。一些方法在运行时,他须要的数据不是任意的,而必须是必定范围内的值,JDK1.5后采用枚举类予以解决。测试
枚举类的定义格式:this
enum 类名{编码
//枚举值spa
}
枚举要注意的细节:
1.枚举类也是一个特殊的类。
2.枚举值默认的修饰符是public ststic final 。
3.枚举值的数据类型是枚举值所属的类的数据类型,枚举值是指向了本类的对象的,其实枚举值就是枚举类的对象。
4.枚举类的构造方法默认的修饰符是private。
5.枚举类能够定义本身的成员变量与成员函数。
6.枚举类能够自定义构造函数,可是构造函数的修饰符必须是private,不然就能够随意建立枚举类的对象了,失去了枚举类的存在乎义。
7.枚举类能够存在抽象的方法,可是枚举值必需要实现抽象的方法。
8.枚举值必需要位于枚举类的第一个语句,不然报错。
枚举类的应用:
针对状况:
一些方法在运行时,他须要的数据不是任意的,而必须是必定范围内的值。
好比:方向 性别 季节 星期
switch语句使用的类型:
byte char short int String 枚举类型
enum Season{ spring,summer,autumn,winter; } enum Person2{ student,worker; } public eclass Demo8 { public static void main(String[] args) { Season season = Season.summer; switch(season){ case spring://只须要写枚举值便可,不须要再声明是该枚举值是属于哪一个类的。 System.out.println("春天..."); break; case summer: System.out.println("夏天..."); break; case autumn: System.out.println("秋天..."); break; case winter: System.out.println("冬天..."); break; } } }
IO流(input output)
IO技术主要的做用是用于解决设备与设备之间的数据传输问题。好比说:键盘--->内存 内存的数据--->硬盘
IO技术的应用场景:
导出报表,上传大头照,下载,解释xml文件
数据保存到硬盘上,该数据就能够作到永久性的保存。数据通常是以文件的形式保存到硬盘上的。
因此sun就使用了一个File类描述了文件或文件夹的属性数据。
(1)File类的构造方法:
File(File parent, String child) (须要操做同一父文件夹下的不一样文件时,使用此构造方法)
根据 parent 抽象路径名和 child 路径名字符串建立一个新 File 实例。
File(String pathname) 指定文件或文件夹的路径建立一个File对象。
经过将给定路径名字符串转换为抽象路径名来建立一个新 File 实例。
File(String parent, String child)
根据 parent 路径名字符串和 child 路径名字符串建立一个新 File 实例。
目录分隔符:
在Windows机器上的目录分隔符是\,在Linux机器上的目录分隔符是/。
使用File下的separator,该常量返回系统默认的分隔符。
注意:在Windows上,/和\均可以使用做为目录分隔符。并且,若是写/的时候,只须要写一个便可。
public class Demo1 { public static void main(String[] args) { File file = new File("F:"+File.separator+"a.txt"); // File file = new File("F:/a.txt"); File parentFile = new File("F:\\"); File file = new File("F:\\","a.txt"); System.out.println("存在吗 "+ file.exists()); // exists 判断该文件是否存在,存在返回true。不然返回false System.out.println("目录分隔符"+ File.separator); } }
(2)File类的经常使用方法
路径问题:
绝对路径:该文件在硬盘上的完整路径,绝对路径通常都是以盘符开头的。
相对路径:资源文件相对于当前程序所在的路径。
.当前路径
..上一级路径
注意:若是程序当前所在的路径与资源文件不是在同一个盘下面,是无法写相对路径的。
File方法:
建立:
createNewFile() 在指定位置建立一个空文件,成功就返回true,若是已存在就不建立而后返回false
mkdir() 在指定位置建立目录(单级文件夹),这只会建立最后一级目录,若是上级目录不存在就抛异常。
mkdirs() 在指定位置建立目录,这会建立路径中全部不存在的目录。
renameTo(File dest) 重命名文件或文件夹,也能够操做非空的文件夹,文件不一样时至关于文件的剪切,剪切时候不能操做非空的文件夹。移动/重命名成功则返回true,失败则返回false。
import java.io.File; import java.io.IOException; public class Demo3 { public static void main(String[] args) throws IOException { File file = new File("F:\\aa"); System.out.println("建立成功?+file.createNewFile()); //createNewFile 在指定位置建立一个空文件,成功就返回true,若是已存在就不建立而后返回false File dir = new File("F:\\a.txt"); System.out.println("建立文件夹"+dir.mkdir()); // mkdir 建立一个文件夹 dir = new File("F:\\aa\\bb"); System.out.println("建立多级文件夹"+ dir.mkdirs()); //renameTo() 若是目标文件与源文件是在同一路径下,那么rename做用是重命名,若是目标文件与源文件不是在同一个路径下,那么rename的做用就是剪切!并且不能操做文件夹,只能操做文件。 File destFile = new File("F:\\aaaaaaw"); System.out.println("重命名成功吗"+file.renameTo(destFile)) ;
删除:
delete() 删除文件或一个空文件夹,若是是文件夹且不为空,则不能删除,成功返回true,失败返回false。
deleteOnExit() 在虚拟机终止时,请求删除此抽象路径名表示的文件或目录,保证程序异常时建立的临时文件也能够被删除通常用来删除临时文件,好比酷狗音乐的在线 试听文件。
二者区别:delete方法会立刻删除一个文件,deleteOnExit在jvm退出时才删除。
判断:
exists() 文件或文件夹是否存在。
isFile() 是不是一个文件,若是不存在,则始终为false。
isDirectory() 是不是一个目录,若是不存在,则始终为false。
isHidden() 是不是一个隐藏的文件或是不是隐藏的目录。
isAbsolute() 测试此抽象路径名是否为绝对路径名。
获取:
getName() 获取文件或文件夹的名称,不包含上级路径。
getPath() 返回绝对路径,能够是相对路径,可是目录要指定
getAbsolutePath() 获取文件的绝对路径,与文件是否存在不要紧
length() 获取文件的大小(字节数),若是文件不存在则返回0L,若是是文件夹也返回0L。
getParent() 返回此抽象路径名父目录的路径名字符串;若是此路径名没有指定父目录,则返回null。
lastModified() 获取最后一次被修改的时间。
文件夹相关:
staic File[] listRoots() 列出全部的根目录(Window中就是全部系统的盘符)
list() 返回目录下的文件或者目录名,包含隐藏文件。对于文件这样操做会返回null。
list(FilenameFilter filter) 返回指定当前目录中符合过滤条件的子文件或子目录。对于文件这样操做会返回null。
listFiles() 返回目录下的文件或者目录对象(File类实例),包含隐藏文件。对于文件这样操做会返回null。
listFiles(FilenameFilter filter) 返回指定当前目录中符合过滤条件的子文件或子目录。对于文件这样操做会返回null。
IO流技术:
IO流分类:
若是是按照数据的流向划分:
判断使用输入流仍是输出流的依据:以当前程序做为一个参照物,观察数据是流入仍是流出,若是流出则使用输出流,若是数据是流入,则使用输入流。
输入流
输出流
若是按照处理的单位划分:
字节流:读取的都是文件中的二进制数据,读取到的二进制数据不会通过任何的处理。
字符流:字符流读取的数据是以字符为单位的,字符流也是读取文件中的二进制数据,不过会把二进制数据转换成咱们能识别的字符。
字符流 = 字节流 +解码
字节流:
输入字节流:
————————| InputStream 全部输入字节流的基类 抽象类
——————————|FileInputStream 读取文件数据的输入字节流
使用FileInputStream读取文件数据的步骤:
1.找到目标文件
2.创建数据的输入通道(FileInputStream对象)
3.读取文件的数据,使用流对象的read()。
4.关闭资源。
//读取方式一缺点:没法读取完整一个文件的数据 public static void readTest1() throws IOException{ //1.找到目标文件 File file = new File("F:\\a.txt"); //创建数据的输入通道 FileInputStream fileInputStream = new FileInputStream(file); //读取文件中的数据 int content = fileInputStream.read(); // read() 读取一个字节的数据,把读取的数据返回。 System.out.println("读到的内容是"+ (char)content);//若不用char强转,返回的是ascii码值 //关闭资源,实际上就是释放资源 fileInputStream.close(); } //方法二:使用循环读取文件的数据 public static void readTest2() throws IOException{ long startTime = System.currentTimeMillis(); //找到目标文件 File file = new File("F:\\1.txt"); //创建数据的输入通道 FileInputStream fileInputStream = new FileInputStream(file); //读取文件的数据 int content = 0; // while((content = fileInputStream.read())!=-1){ System.out.print((char)content); } //关闭资源 fileInputStream.close(); } //方式三:使用缓冲数组读取 缺点:没法读取完整一个文件的数据,由于数组容量有限。 public static void readTest3() throws IOException{ //找到目标文件 File file = new File("F:\\a.txt"); //创建数据的输入通道 FileInputStream fileInputStream = new FileInputStream(file); //创建缓冲字节数组,读取文件数据 byte[] buf = new byte[1024]; //至关于超市里面的购物车 缓冲数组的长度通常是1024的倍数,由于与计算机的处理单位相符 int length = fileInputStream.read(buf); //若是使用read方法读取数据传入字节数组,那么数据是存储到字节数组中的,而这时候read的返回值表示的是本次读取了几个字节数据到字节数组中。 System.out.println("length:"+ length); //使用字节数组构建字符串 String content = new String(buf,0,length); System.out.println("内容"+ content); //关闭资源 fileInputStream.close(); } //方式四:使用缓冲数组配合循环一块儿读取 public static void readTest4() throws IOException{ long startTime = System.currentTimeMillis(); //找到目标文件 File file = new File("F:\1.jpg"); //创建数据的输入通道 FileInputStream fileInputStream = new FileInputStream(file); //创建缓冲数组配合循环读取文件的数据 int length = 0; //保存每次读取到的字节个数 byte[] buf = new byte[1024]; //每次读取1024个,采起覆盖的方式 while((length = fileInputStream.read(buf))!=-1){ System.out.print(new String(buf,0,length)); } //关闭资源 fileInputStream.close(); }
通常使用第四种。
问题一:读取完一个文件的数据的时候,是否须要当即释放资源?
答案:资源文件一旦使用完毕应该立刻释放,不然其余的程序没法对该资源进行操做。
输出字节流:
————————| OutputStream 是全部输出字节流的父类。抽象类。
——————————| FileOutputStream 向文件输出数据的输出字节流
FileOutputStream使用方法:
1.找到目标文件
2.创建数据的输出通道
3.把数据写出
4.关闭资源
static void writeDate() throws IOException{ File file = new File("F://1.txt"); FileOutputStream fileoutputstream = new FileOutputStream(file); String a= "abc"; byte date[] = a.getBytes(); fileoutputstream.write(date); }
FileOutputStream须要注意的细节:
1.使用FileOutputStream的时候,若是目标文件不存在,那么会自动建立目标文件对象。
2.使用FileOutputStream写数据的时候,若是目标文件已经存在,那么会先清空目标文件中的数据,而后再写入数据。(调用另外一构造方法便可,以下)
3.使用FileOutputStream写数据的时候,若是目标文件已经存在,须要在原来数据基础上追加数据的时候应该使用newFileOutputStream(file,true)这一个构造函数
4.使用FileOutputStream的write方法写数据的时候,虽然接收的是一个int类型的数据,可是真正写书的只是一个字节的数据,只是把低八位的二进制数据写出,其余二十四位数据所有丢弃。
IO异常处理
public static void readTest() { FileInputStream fileInputStream = null; try { // 找到目标文件 File file = new File("F:\\aaaaa.txt"); // 创建数据输入通道 fileInputStream = new FileInputStream(file); // 创建缓冲数组读取数据 byte[] buf = new byte[1024]; int length = 0; while ((length = fileInputStream.read(buf)) != -1) { System.out.print(new String(buf, 0, length)); } } catch (IOException e) { /* * 处理的代码。首先你要组织后面的代码执行,并且须要通知调用者这里出错了 * throw new RuntimeException(e); * 把IOException传递给RuntimeException包装一次,而后再抛出,这样作的目的是为了让调用者使用边的更加灵活。e-cause */ System.out.println("读取文件出错"); throw new RuntimeException(e); } finally { try { if (fileInputStream != null) { fileInputStream.close(); System.out.println("关闭资源成功"); } } catch (IOException e) { System.out.println("关闭资源失败"); throw new RuntimeException(e); } } } }
缓冲输入字节流:
输入字节流体系:
————————| InputStream 输入字节流的基类,抽象。
——————————| FileInputStream 读取文件数据的输入字节流。
——————————| BufferedInputStream 缓冲输入字节流(凡是缓冲字节流都以Buffer开头)它的出现主要是为了提升读取文件数据的效率。
其实该类内部只不过是维护了一个8KB字节的数组。
背景:咱们清楚读取文件数据使用缓冲数组读取效率更高,sun公司也知道使用缓冲数组读取效率更高,那么sunge给咱们提供了一个——缓冲输入字节流对象,,让咱们能够更高效率的读取文件。
效率提升的缘由:不带缓冲的操做,每读一个字节就要写入一个字节,因为涉及磁盘的IO操做相比内存的操做要慢不少,因此不带缓冲的流效率很低,而带缓冲的流,能够一次读不少字节,但不向磁盘中写入,只是先放到内存里。等凑够了缓冲区大小的时候一次性写入磁盘,这种方式能够减小磁盘操做次数,速度就会提升不少。
使用BufferedInputStream步骤:
1.找到目标文件
2.创建数据的输入通道 FileInputStream对象
3.创建缓冲输入字节流 BufferedInputStream对象,并把FileInputStream传入。
4.读取文件数据
5.关闭资源
注意:凡是缓冲流,都不具有读写文件的能力!!!
static void readDate() throws IOException{ FileInputStream fileinputStream = new FileInputStream("F:\\1.txt"); BufferedInputStream bufferedinputstream = new BufferedInputStream(fileinputStream); int content = 0 ; while((content = bufferedinputstream.read())!=-1){ System.out.println((char)content); } bufferedinputstream.close(); }
缓冲输出字节流
————————| OutputStream 全部输出字节流的基类 抽象类
——————————| FileOutputStream 向文件输出数据的输出字节流
——————————| BufferedOutputStream 缓冲输出字节流 内部也是维护了一个8KB的字节数组而已。
BufferedOutputStream出现的目的是为了提升写数据的效率
使用BufferedOutputStream的步骤:
1.找到目标文件
2.创建数据的输出通道
3.创建缓冲输出字节流对象
4.把数据写出
BufferedOutputStream要注意的细节:
使用BufferedOutputStream写数据的时候,它的write方法是先把数据写到它内部维护的字节数组中。若是须要把数据真正的写到硬盘上面,如须要调用flush方法(刷新次缓冲的输出流)或close方法,或者是内部维护的字节数组已经填满数组的时候。
字符流
输入字符流
字节流:字节流读取的是文件中的二进制数据,读到的数据并不会帮你转换成你看得懂的字符。
字符流:字符流会把读取到的二进制数据进行对应的编码与解码工做,字符流=字节流+解码
输入字符流:
————————| Reader 输入字符流的基类 抽象类
——————————| FileReader 读取文件的输入字符流。
——————————| BufferedReader 缓冲输入字符流。缓冲后输入字符流出现的目的是为了提升读取文件字符的效率和拓展了FileReader的功能。
FileReader的用法:
1.找到目标文件。
2.创建数据的输入通道。
3.读取字符。
4.关闭资源。
可是效率低,使用缓冲数组,每次接受数组容量个数的字符。
public static void readTest2() throws IOException{ File file = new File("F:\\1208project\\day21\\src\\day21\\Demo1.java"); FileReader fileReader = new FileReader(file); char[] buf = new char[1024]; int length = 0 ; while((length = fileReader.read(buf))!=-1){ System.out.print(new String(buf,0,length)); } } public static void readTest1() throws IOException{ File file = new File("F:\\1208project\\day21\\src\\day21\\Demo1.java"); FileReader fileReader = new FileReader(file); int content = 0 ; while((content = fileReader.read())!=-1){ System.out.print((char)content); } fileReader.close(); }
缓冲输入字符流
BufferedReader的使用步骤:
1.找到目标文件。
2.创建数据的输入通道。
3.创建缓冲数组字符流。
4.读取数据。
记住:缓冲流都不具有读写文件的能力。
输出字符流
————————| Write 输出字符流的基类 抽象类
——————————| FileWriter 向文件输出数据的输出字符流
——————————| BufferedWriter 缓冲输出字符流 缓冲输出字符流的做用:提升FileWriter的写数据效率与提升FileWriter的功能。
FileWriter的使用步骤:
1.找到目标文件
2.创建数据输出通道
3.写出数据
4.关闭通道
FileWriter要注意的事项:
1.使用FileWriter写数据的时候,FileWriter内部是维护了一个1024个字符数组的,写数据的时候回先写入到它内部维护的字符数组中,若是把数据真正写到硬盘上,须要调用flush或者是close方法或者是填满了内部的字符数组。
2.使用FileWriter的时候,若是目标文件不存在,那么会自动建立目标文件。
3.使用FileWriter的时候,若是目标文件已经存在了,那么会默认先清空文件中的数据,而后再写入数据,;若是须要在原基础上追加数据,须要使用new FileWriter(File boolean),其中boolean为true。
字符流具有了解码功能,方便不少。
public static void writeTest1() throws IOException{ File file = new File("F:\\a.txt"); FileWriter fileWriter = new FileWriter(file,true); String data = "你们好"; fileWriter.write(data); // // fileWriter.flush(); fileWriter.close(); }
FileReader须要注意的事项:
使用FileReader字符流copy图片时,会先读取图片的每一个值,而后去码表中查找对应的字符,而后在读取该字符,可是当码表中没有改值对应的字符时,会返回一个字节的未知字符对应的数据,会出现原数据与未知字符对应的数据字节长度不对应,这样就会形成照片损坏。
什么时候使用字符流,什么时候使用字节流?依据是什么?
1.读写字符数据的时候使用字符流。
2.若是读写的数据都不须要转换成字符的时候,使用字节流。
缓冲输出字符流
缓冲输出字符流的使用步骤:
1.找到目标文件
2.创建数据的输出通道
3.创建缓冲输出流对象
4.写出数据
BufferedWriter内部只不过是提供了一个8192长度的字符数据做为缓冲区而已,拓展了FileWriter功能(newLine)
虽然它的write方法形参是char,可是给字符串便可直接输出。
模拟注册登陆界面
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.Scanner; public class Welcome { static Scanner scanner = new Scanner(System.in); public static void main(String[] args) throws IOException { while(true){ System.out.println("请键入指令,a为注册,b为登陆"); String option = scanner.next(); if("a".equalsIgnoreCase(option)){ //System.out.println("注册"); reg(); } else if("b".equalsIgnoreCase(option)){ //System.out.println("登陆"); login(); } else{ System.out.println("输入有误,请从新输入"); } } } public static void reg() throws IOException{ System.out.println("请输入用户名"); String userName = scanner.next(); System.out.println("请输入密码"); String password = scanner.next(); BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("F:\\reg.txt")); String info = userName+ " " +password; bufferedWriter.write(info); bufferedWriter.newLine(); bufferedWriter.close(); } public static void login() throws IOException{ System.out.println("请输入用户名"); String loginName = scanner.next(); System.out.println("请输入登陆密码"); String loginPassword = scanner.next(); BufferedReader bufferedReader = new BufferedReader(new FileReader("F:\\reg.txt")); String info = loginName+ " " +loginPassword; String line = null; boolean isLogin= false; while((line=bufferedReader.readLine())!=null){ if(line.equals(info)){ isLogin = true; break; } } if(isLogin){ System.out.println("欢迎登录,登录成功"); } else{ System.out.println("该用户名不存在,请从新注册"); } } }
对象的输入输出流
做用:用于写对象的信息和读取对象的信息,对象信息一旦写到文件上那么对象的信息就能够作到持久化了。
对象输出流(ObjectOutputStream)
对象输入输出流要注意的细节:
1.若是对象须要被写出到文件上,那么对象所属的类必需要实现Serializable接口,Serializable接口没有任何的方法,只不过是一个标识接口而已。
对象的序列化:定义方法把对象的信息写到硬盘上。注意,写出来的文件是为了JVM看的,不是给咱们看的。
对象的反序列化:把文件中的对象信息读取出来。
2.注意:反序列化时建立对象并不会调用构造方法。(对象克隆也不会)因此,建立对象时必定会调用构造方法这句话是错的!
3.serialVersionUID是用于记录class文件的版本信息打印的,serialVersionUID合格数字是经过一个类的类名,成员,包名,工程名算出的一个数字。
4.使用ObjectInputStream反序列化的时候,ObjectInputStream会先读取文件中的serialVersionUID,而后与本地的class文件的serialVersionUIDemo进行对比,若是两个ID号不一致,那么反序列化就失败了。
5.若是序列化与反序列化的时候可能会修改类的成员,那么最好一开始就给这个类指定一个serialVersionUID,若是一类已经指定了UID,那么在序列化和反序列化的时候,JVM就不会再算这个UID了。
6.若是一个对象的某个数据不想被序列化到硬盘上,可使用关键字transien修饰。
7.若是一个类维护了另一个类的引用,那么另一个类也须要实现serialzable接口。
class Address implements Serializable{ String country; String city; public Address(String country,String city){ this.country = country; this.city = city; } } class User implements Serializable{ private static final long serialVersionUID = 1L; String userName ; String password; transient int age; // transient 关键字 Address address ; public User(String userName , String passwrod) { this.userName = userName; this.password = passwrod; } public User(String userName , String passwrod,int age,Address address) { this.userName = userName; this.password = passwrod; this.age = age; this.address = address; } @Override public String toString() { return "名字"+this.userName+ " 密码"+ this.password+" 年龄"+this.age+"地址"+this.address.city; } } public class Demo3 { public static void main(String[] args) throws IOException, Exception { writeObj(); // readObj(); } //把文件中的对象信息读取出来——>对象的反序列化 public static void readObj() throws IOException, ClassNotFoundException{ //找到目标文件 File file = new File("F:\\obj.txt"); //创建数据的输入通道 FileInputStream fileInputStream = new FileInputStream(file); //创建对象的输入流对象 ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); //读取对象信息 User user = (User) objectInputStream.readObject(); // System.out.println("对象的信息"+ user); } //对象的序列化:定义方法把对象的信息写到硬盘上 public static void writeObj() throws IOException{ // Address address = new Address("",""); User user = new User("admin","123",15,address); //找到目标文件 File file = new File("F:\\obj.txt"); //创建数据的输出通道 FileOutputStream fileOutputStream = new FileOutputStream(file); //创建对象的输入流对象 ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); //写对象信息 objectOutputStream.writeObject(user); //关闭通道 objectOutputStream.close(); } }