【Java-----IO流(八)之对象专属流详解】

本文详细介绍了Java中的序列化和反序列化概念,包括它们的作用、实现方式、对象流的使用以及Serializable接口。序列化用于将对象转换为字节流以便存储或传输,而反序列化则是将字节流恢复为对象。文章还讨论了序列化版本号的重要性,给出了对象序列化和反序列化的代码示例,并解释了transient关键字的用途。此外,还提到了序列化的优点,如永久保存对象和方便网络传输。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

序列化和反序列化定义

  • 序列化:指把Java对象转换为字节序列的过程
  • 反序列化:指把字节序列恢复为Java对象的过程

序列化和反序列化的作用

  • 序列化:在传递和保护对象时,保证对象的完整性和可传递性,对象转换为有序字节流,以便在网络上传输或者保护在本地文件中
  • 反序列化:根据字节流中保护的对象状态及描述信息,通过反序列化重建对象

序列化和反序列化的实现

  • 对象序列化流:ObjectOutputStream
  • 对象反序列化流:ObjectInputStream

构造方法

  • ObjectOutputStream(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream
  • ObjectInputStream(InputStream in):创建从指定的InputStream读取的ObjectInputStream

序列化对象和反序列化对象的方法

  • void writeObject(Object obj):将指定的对象写入ObjectOutputStream
  • Object readObject():从ObjectInputStream读取一个对象

Serializable接口

参与序列化和反序列化的对象,必须实现Serializable接口。否则会报错:Java.io.NotSerializableException

通过源代码发现,Serializable接口只是一个标志接口:

public interface Serializable{

}

这个接口中什么代码都没有,它是起标识作用的,Java虚拟机看到这个类实现了这个接口,会为该类自动生成一个序列化版本号

序列化版本号的作用

Java语言中是采用什么机制来区分类的?

一:首先通过类名进行比较,如果类名不一样,肯定不是同一个类

二:如果类名一样,则需要靠序列化版本号进行区分

自动生成序列化版本号的缺点:一旦代码确定之后,不能进行后续的修改,因为只要修改,必然会重新编译,此时会生成全新的序列化版本号,这个时候Java虚拟机会认为这是一个全新的类

结论:凡是一个类实现了Serializable接口,建议给该类提供一个固定不变的序列化版本号,这样,以后这个类即使代码修改了,但是版本号不变,Java虚拟机会认为是同一个类。

例:

public class Student implements Serializable {
	//手动写出序列号
	private static final long serialVersionUID=1L;
	int age;
	String name;

对象序列化代码实现

对象类:

public class Student implements Serializable {
	int age;
	String name;
	public Student() {
		
	}
	public Student(int age,String name) {
		this.name=name;
		this.age=age;
	}
	public void setName(String name) {
		this.name=name;
	}
	public String getName() {
		return name;
	}
	public void setAge(int age) {
		this.age=age;
	}
	public int getAge() {
		return age;
	}
    public String toString() {
		return "Student{name="+name+","+"age="+age+"}";
	}
}

序列化:

public static void main(String[] args) throws IOException {
	//创建对象
	Student s=new Student(3,"Alice");
	//序列化
	FileOutputStream fos=new FileOutputStream("D:\\aaa\\student.txt");
	ObjectOutputStream oos=new ObjectOutputStream(fos);
	//序列化对象
	oos.writeObject(s);
	oos.flush();
	oos.close();
}

反序列化对象代码实现

反序列化:

//反序列化
FileInputStream fis=new FileInputStream("D:\\aaa\\student.txt");
ObjectInputStream ois=new ObjectInputStream(fis);
//反序列化对象
Object obj=ois.readObject();
//输出对象
System.out.println(obj);
ois.close();
//输出:Student{name=Alice,age=3}

一次序列化和反序列化多个对象

序列化:

//创建集合存放对象
List<Student> studentList=new ArrayList<Student>();
//创建对象
Student s1=new Student(3,"Alice");
Student s2=new Student(5,"bob");
Student s3=new Student(2,"rose");
//将对象存入集合
studentList.add(s1);
studentList.add(s2);
studentList.add(s3);
//序列化
FileOutputStream fos=new FileOutputStream("D:\\aaa\\student.txt");
ObjectOutputStream oos=new ObjectOutputStream(fos);
//序列化一个集合
oos.writeUnshared(studentList);
oos.flush();
oos.close();

反序列化:

//反序列化
FileInputStream fis=new FileInputStream("D:\\aaa\\student.txt");
ObjectInputStream ois=new ObjectInputStream(fis);
//反序列化集合
List<Student> list=(List<Student>)ois.readObject();
//遍历集合并输出
for(Student s:list) {
	System.out.println(s);
}
ois.close();
/*
输出:Student{name=Alice,age=3}
     Student{name=bob,age=5}
     Student{name=rose,age=2}
*/

transient关键字

transient关键字表示游离的,不参与序列化:

//name用transient关键字修饰,表示name不参与序列化操作
private transient String name;

序列化优点

  1. 将对象转为字节流存储到硬盘上,当JVM停机时,字节流还会在硬盘上默默等待,等待下一处JVM的启动,把序列化的对象通过反序列化为原来的对象,并且序列化的二进制序列能够减少存储空间(永久性保存对象)
  2. 序列化成字节流的对象可以进行网络传输(二进制形式),方便网络传输
  3. 通过序列化可以在进程间传递对象

<think>我们正在使用IntelliJ IDEA,并希望集成GeoTools库的gt-geotiff模块,版本28.2。以下是步骤: 1. **添加Maven依赖**:由于GeoTools通常通过Maven仓库分发,我们可以在项目的pom.xml文件中添加依赖。 2. **配置GeoTools Maven仓库**:GeoTools的库不在中央仓库中,因此需要添加其专属仓库。 3. **在IntelliJ IDEA中操作**:我们将使用Maven项目,因此需要创建或修改pom.xml。 ### 步骤详解 #### 1. 创建Maven项目(如果尚未创建) 在IntelliJ IDEA中,选择File -> New -> Project...,然后选择Maven,按照向导创建项目。 #### 2. 修改pom.xml文件 在项目的pom.xml文件中,我们需要添加GeoTools的仓库和依赖。 首先,添加GeoTools的仓库(在`<repositories>`标签内): ```xml <repositories> <repository> <id>osgeo</id> <name>OSGeo Release Repository</name> <url>https://repo.osgeo.org/repository/release/</url> <snapshots> <enabled>false</enabled> </snapshots> <releases> <enabled>true</enabled> </releases> </repository> </repositories> ``` 然后,添加gt-geotiff模块的依赖(在`<dependencies>`标签内): ```xml <dependency> <groupId>org.geotools</groupId> <artifactId>gt-geotiff</artifactId> <version>28.2</version> </dependency> ``` #### 3. 刷新Maven项目 在IntelliJ IDEA中,当修改pom.xml后,IDE通常会提示自动导入更改。如果没有,可以右键点击pom.xml文件,选择“Maven”->“Reload Project”来下载依赖。 #### 4. 使用gt-geotiff 现在,你可以在代码中导入GeoTools的类并使用。例如,读取一个GeoTIFF文件: ```java import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.gce.geotiff.GeoTiffReader; import java.io.File; public class ReadGeoTiff { public static void main(String[] args) throws Exception { File file = new File("path/to/your/file.tif"); GeoTiffReader reader = new GeoTiffReader(file); GridCoverage2D coverage = reader.read(null); // 处理coverage对象... reader.dispose(); } } ``` ### 注意事项 - 确保你的项目使用Java 11或更高版本,因为GeoTools 28.x需要Java 11+。 - 如果遇到依赖冲突,可能需要排除一些冲突的依赖,或者调整版本。 ### 常见问题解决 - **依赖下载失败**:检查网络连接,确保可以访问https://repo.osgeo.org。 - **版本冲突**:使用Maven的依赖树分析(`mvn dependency:tree`)来查看冲突,并排除不需要的依赖。 通过以上步骤,你应该能够在IntelliJ IDEA中成功使用GeoTools的gt-geotiff模块。 §§相关问题§§ 1. 如何在非Maven项目中使用GeoTools库? 2. GeoTools支持哪些其他地理空间数据格式? 3. 如何读取GeoTIFF文件的元数据? 4. 使用GeoTools时遇到依赖冲突怎么办?</think>### 在 IntelliJ IDEA 中使用 GeoTools gt-geotiff 28.2 的步骤 #### 1. **创建 Maven 项目** - 打开 IntelliJ IDEA → 新建项目 → 选择 **Maven** - 确保 JDK 版本 ≥ 11(GeoTools 28.x 需要 Java 11+) #### 2. **配置 `pom.xml`** 添加 GeoTools 仓库和依赖: ```xml <repositories> <!-- 添加 GeoTools 官方仓库 --> <repository> <id>osgeo</id> <name>OSGeo Release Repository</name> <url>https://repo.osgeo.org/repository/release/</url> <releases><enabled>true</enabled></releases> <snapshots><enabled>false</enabled></snapshots> </repository> </repositories> <dependencies> <!-- 添加 gt-geotiff 依赖 --> <dependency> <groupId>org.geotools</groupId> <artifactId>gt-geotiff</artifactId> <version>28.2</version> </dependency> <!-- 添加日志依赖(避免运行时警告) --> <dependency> <groupId>org.geotools</groupId> <artifactId>gt-main</artifactId> <version>28.2</version> </dependency> </dependencies> ``` #### 3. **刷新 Maven 依赖** - 右键点击 `pom.xml` → **Maven** → **Reload Project** - 等待依赖下载完成(查看底部进度条) #### 4. **代码示例:读取 GeoTIFF 文件** ```java import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.gce.geotiff.GeoTiffReader; import java.io.File; public class GeoTiffExample { public static void main(String[] args) { try { // 1. 加载 GeoTIFF 文件 File tiffFile = new File("path/to/your/image.tif"); GeoTiffReader reader = new GeoTiffReader(tiffFile); // 2. 读取栅格数据 GridCoverage2D coverage = reader.read(null); System.out.println("坐标系: " + coverage.getCoordinateReferenceSystem()); // 3. 释放资源 reader.dispose(); } catch (Exception e) { e.printStackTrace(); } } } ``` #### 5. **解决常见问题** - **依赖冲突**:如果报 `NoSuchMethodError`,在 `pom.xml` 中添加: ```xml <dependencyManagement> <dependencies> <dependency> <groupId>org.geotools</groupId> <artifactId>gt-bom</artifactId> <version>28.2</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> ``` - **缺少 JAI 库**:GeoTIFF 处理需要 JAI 扩展,在 `pom.xml` 中添加: ```xml <dependency> <groupId>org.geotools</groupId> <artifactId>gt-coverage</artifactId> <version>28.2</version> </dependency> ``` #### 6. **运行配置** - 添加 JVM 参数避免坐标系警告: ``` -Dorg.geotools.referencing.forceXY=true ``` ### 验证是否成功 1. 运行示例代码,检查是否输出坐标系信息(如 `EPSG:4326`) 2. 在 **External Libraries** 中查看是否包含 `gt-geotiff-28.2.jar` > **注意**:GeoTools 模块需保持版本一致(所有依赖尽量用 `28.2`)[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值