1 Properties 类介绍
这个类表示一个持久的属性集。它可以保存到流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。
特点:
1. Hashtable
的子类,实现map接口,map集合中的方法都可以用;
2. 该集合没有泛型,键值都是字符串;
3. 它是一个可以持久化的属性值,键值可以存储到集合中,也可以存储到持久化的设备(硬盘等)。键值的来源也可以是持久化的设备。
1.1 使用Properties集合,存储键值对
setProperty
等同于Map接口中的put
;setProperty(String key,String value)
;- 通过键获取值,
getProperty(String key)
;
public static void function(){
Properties pro=new Properties();
pro.setProperty("a","1");
pro.setProperty("b","2");
pro.setProperty("c","3");
pro.setProperty("d","4");
System.out.println(pro);
String value = pro.getProperty("c");
System.out.println(value);
//将集合中的键存储到Set集合,类似于Map接口方法keySet
Set<String> set=pro.stringPropertyNames();
for(String key:set){
System.out.println(key+"->"+pro.getProperty(key));
}
}
1.2 Properties 集合特有的方法load
load(InputStream)
load(Reader r)
- 传递任意字节或者字符输入流;
- 流对象读取文件中的键值对,保存到集合;
public static void function_1()throws IOException{
Properties pro=new Properties();
FileReader fr=new FileReader("h:\\test\\pro.properties");
pro.load(fr);
fr.close();
System.out.println(pro);
}
1.3 Properties 集合特有方法store
store(OutputStream out)
store(Writer w)
- 接收所有的字节或者字符的输出流,将集合中的键值对写回文件保存;
2 对象的序列化与反序列化
- 对象中的数据,以流的形式,写入到文件中保存,过程称为写出对象,对象的序列化。
OnjectOutputStream
将对象写到文件中,实现序列化;- 在文件中,以流的形式将对象读取出来,读取对象,对象的反序列化;
ObjectInputStream
将文件对象读取出来;
2.1 ObjectOutputStream
- 构造方法
ObjectOutputStream(OutputStream out)
; - 传递任意字节输出流;
void writeObject(Object obj)
写出对象的方法
import java.io.Serializable;
public class Person implements Serializable{
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" + "name='" + name + '\'' + ", age=" + age + '}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (age != person.age) return false;
return name != null ? name.equals(person.name) : person.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public static void function()throws IOException {
//创建字节输出流,封装文件
FileOutputStream fos=new FileOutputStream("h:\\test\\person.txt");
//创建写出对象的序列化流的对象
ObjectOutputStream oos=new ObjectOutputStream(fos);
Person p=new Person("Mike",25);
oos.writeObject(p);
oos.close();
}
2.2 ObjectInputStream
- 构造方法:
ObjectInputStream(InputStream in)
Object readObject()
读取对象;
public static void function_1() throws IOException, ClassNotFoundException {
FileInputStream fis=new FileInputStream("h:\\test\\person.txt");
ObjectInputStream ois=new ObjectInputStream(fis);
Object obj=ois.readObject();
System.out.println(obj);
ois.close();
}
2.3 静态不能序列化
- 静态属于类的,不属于对象
3 transient
(瞬态)关键字
- 阻止成员变量序列化;
4 Serializable
接口
- 没有抽象方法;
- 只起标志的作用;
5 序列化中自定义的序列号
5.1 序列化中的序列号冲突问题
- 当一个类实现Serializable接口后,创建对象并将对象写入文件,之后更改了源代码(比如:将成员变量的修饰符有private改成public),再次从文件中读取对象时会报异常。
5.2 自定义
public class Person implements Serializable{
public String name;
private int age;
//类自定义序列号,编译器不会计算序列号
private static final long serialVersionUID = 42L;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" + "name='" + name + '\'' + ", age=" + age + '}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (age != person.age) return false;
return name != null ? name.equals(person.name) : person.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}