定义一个实现序列化接口的bean 并重写readObject和writeObject方法
实现类中所有的字段都使用transient 修饰、表示在序列化的时候不保存该字段
package mytest;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class TestBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private transient Long code;
private transient String text;
private transient Date d;
private transient List<String> list;
private transient List<String> list2;
public Long getCode() {
return code;
}
public void setCode(Long code) {
this.code = code;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Date getD() {
return d;
}
public void setD(Date d) {
this.d = d;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
public List<String> getList2() {
return list2;
}
public void setList2(List<String> list2) {
this.list2 = list2;
}
/**
* 序列化对象的方法的writeObject
* @param os
* @throws IOException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
private void writeObject(ObjectOutputStream os) throws IOException, IllegalArgumentException,
IllegalAccessException {
os.defaultWriteObject();//java对象序列化默认操作
Field[] fs = this.getClass().getDeclaredFields();
for (Field field : fs) {
String f = field.getName();
if ("serialVersionUID".equals(f))
continue;
int mod = field.getModifiers();
if (Modifier.isTransient(mod))
setObjectOutputStream(os, field);
}
}
/**
* 反序列化对象的方法readObject
* @param is
* @throws IOException
* @throws ClassNotFoundException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException, IllegalArgumentException,
IllegalAccessException {
is.defaultReadObject();//java对象反序列化默认操作
Field[] fs = this.getClass().getDeclaredFields();
for (Field field : fs) {
String f = field.getName();
if ("serialVersionUID".equals(f))
continue;
int mod = field.getModifiers();
if (Modifier.isTransient(mod))
readObjectInputStream(is, field);
}
}
@SuppressWarnings("unchecked")
private void setObjectOutputStream(ObjectOutputStream os, Field field) throws IOException,
IllegalArgumentException, IllegalAccessException {
Class<?> type = field.getType();
Object v = field.get(this);
if (type == String.class || type == Long.class || type == Integer.class) {
os.writeObject(v);
} else if (type == java.util.Date.class || type == java.sql.Date.class) {
os.writeObject(v);
} else if (type == int.class) {
os.writeInt(Integer.parseInt(v.toString()));
} else if (type == long.class) {
os.writeLong(Long.parseLong(v.toString()));
} else if (type == List.class) {
List<String> l = (List<String>) v;
os.writeInt(l.size());
for (String s : l) {
os.writeObject(s);
}
}
}
private void readObjectInputStream(ObjectInputStream is, Field f) throws IllegalArgumentException,
IllegalAccessException, IOException, ClassNotFoundException {
Class<?> type = f.getType();
if (type == String.class || type == Long.class || type == Integer.class) {
f.set(this, is.readObject());
} else if (type == java.util.Date.class || type == java.sql.Date.class) {
f.set(this, is.readObject());
} else if (type == int.class) {
f.set(this, is.readInt());
} else if (type == long.class) {
f.set(this, is.readLong());
} else if (type == List.class) {
int size = is.readInt();
List<String> setList = new ArrayList<String>();
for (int i = 0; i < size; i++) {
Object data = is.readObject();
setList.add(data.toString());
}
f.set(this, setList);
}
}
}
测试类
package mytest;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;
public class SerializeTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
TestBean tb = new TestBean();
// tb.setCode(null);
tb.setText("中文");
tb.setD(new Date());
List<String> list = new ArrayList<String>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
tb.setList(list);
List<String> list2 = new ArrayList<String>();
list2.add("1");
list2.add("2");
list2.add("3");
list2.add("4");
list2.add("5");
tb.setList2(list2);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(tb);
out.flush();
out.close();
System.out.println(new String(bos.toByteArray()));
System.out.println(bos.size());
ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
TestBean tb2 = (TestBean) in.readObject();
System.out.println(tb2.getD());
}
}
经过测试一个序列化对象的大小有:170字节
经过处理后大小变成:92字节
代码写得比较丑、以后再慢慢优化
只是为了保存一下
分享到:
相关推荐
为了减少序列化后的字符串大小,它还移除了多余的分隔符。 2. **自定义反序列化函数** `DeserializeObject<T>`: 这个泛型函数接收一个字符串`s`,根据字符串反序列化回指定类型`T`的对象。它首先获取目标类型的...
3. **自定义类型支持**:Unity的内置序列化系统可能对某些自定义类型处理不佳,而DreamSerialize可能允许开发者自定义序列化逻辑,确保所有数据类型都能正确地被序列化和反序列化。 4. **轻量级**:为了适应游戏...
6. **自定义序列化行为** 开发者可以通过实现特定接口(如`.NET`中的`ISerializable`)或使用特性(如`[Serializable]`、`[XmlElement]`等)来自定义序列化和反序列化的行为。这可以用来排除某些字段、指定序列化...
序列化对象时需要注意安全问题,因为恶意用户可以构造特殊的序列化数据来执行任意代码。为了避免这种情况,应当避免对不可信的数据进行反序列化,并且限制哪些类可以被序列化。 8. **ObjectStreamClass**: `java...
- 对于经常访问的数据,可以考虑使用缓存机制,如Redis或本地缓存,减少序列化和反序列化的次数。 12. **预分配文件大小**: - 在序列化前预分配文件大小,可以减少磁盘碎片,提高写入速度。 13. **使用池化技术...
- `java.io.ObjectOutputStream`:对象输出流,提供了`writeObject(Object obj)`方法用于序列化对象,将对象转换为字节流并写入到输出流(如文件输出流)。 - `java.io.ObjectInputStream`:对象输入流,提供了`...
这对于我们自定义序列化逻辑或优化现有应用的性能都非常有价值。 5. **应用场景** - 在分布式服务间通信中,Hessian常用于构建轻量级的RPC(远程过程调用)框架,提供高效的二进制序列化能力。 - 在存储场景下,...
- **可扩展性**:可以通过自定义序列化器来支持自定义类型。 - **高效性**:通过模板元编程技术优化序列化过程,减少运行时开销。 #### 序列化模式 Boost序列化支持两种主要模式:侵入式(Intrusive)和非侵入式...
3. **类型安全的反序列化**:Jackson提供了类型令牌(`TypeReference`)或自定义类型解析器(`JsonDeserializer`),以确保反序列化时保持类型安全,尤其是在处理复杂数据结构时。 4. **流式API**:除了基于树模型...
8. **用户自定义配置**:允许用户保存特定的布局设置,比如自定义的窗口大小和位置,可以通过改进序列化机制来实现。 文件名为`GenericDockPanelSuite`可能表示这是一个通用的DockPanel Suite实现,可能包含了对...
在Netty中实现序列化,通常需要自定义`MessageToByteEncoder`和`MessageToMessageDecoder`,这两个类负责编码和解码数据。编码器将应用程序对象转化为字节数组,解码器则反之。例如,使用protobuf时,可以创建...
序列化(Serialization)是将数据对象转换为可以存储或传输的格式的过程。在本例中,它涉及将结构体实例转换为二进制流,以便保存到文件。这样做的好处在于,二进制格式通常占用更少的存储空间,并且可以更快地读取...
序列化是指将数据结构或对象转换为字节流的过程,以便可以存储在磁盘上或在网络中传输。反序列化则是将字节流恢复为原始数据结构或对象的过程。在R中,`saveRDS()` 和 `readRDS()` 函数是常用的序列化工具,但它们...
3. **性能优化**:cpp-cmp设计时考虑了性能,尽可能减少不必要的内存分配和拷贝,以提高序列化和反序列化速度。 4. **错误处理**:在处理过程中,cpp-cmp会检查数据的有效性和一致性,如果出现错误,它会抛出异常,...
// 自定义序列化函数 function my_serialize($obj_array) { return base64_encode(gzcompress(serialize($obj_array))); } // 自定义反序列化函数 function my_unserialize($str) { return unserialize...
9. **减少序列化后的JSON大小**:JSON.NET提供了各种选项来压缩JSON输出,例如忽略空值、去除默认值、使用引用等,以减小网络传输的数据量。 10. **可扩展性**:JSON.NET的源代码开放,允许开发者根据需要进行定制...
2. **减少序列化开销**:仅序列化必要的字段,避免对大型对象或复杂数据结构的序列化。 3. **利用缓存**:对经常使用的对象进行缓存,避免重复的序列化和反序列化操作。 4. **并行处理**:如果可能,利用多线程或...
26. **NotWriteDefaultValue**:不输出默认值,减少序列化后的文本大小。 27. **BrowserSecure**:确保 JSON 输出安全,避免 XSS 攻击。 28. **IgnoreNonFieldGetter**:忽略非字段 getter 方法。 29. **...
综上所述,本实例主要涵盖了Spark中的Kryo序列化库的使用,包括启用Kryo、注册自定义类、优化配置以及自定义序列化策略。通过深入理解和应用这些知识,开发者可以提高Spark应用程序的执行效率和内存管理能力。