- Java 8:Lambda 序列化?
- Java 8 lambda 最佳实践
- Java 8 lambda 表达式 10 个示例
- Java8 lambda 表达式 10 个示例
- Java8 Lambda 表达式和流操作如何让你的代码变慢 5 倍
- Java8:Lambda 表达式增强版 Comparator 和排序
- Java 8 LongAdders:管理并发计数器的正确方式
- Java 8 Optional 类深度解析
- Java8 中的 java.util.Random 类
- Java8 中的简易并发
- Java8 学习:Lambda 表达式、Stream API 和功能性接口 — 教程、资源、书籍和实例
- Java8 并发教程:Threads 和 Executors
- Java 8 新特性之旅:使用 Stream API 处理集合
- Java 8 新特性探究(一)通往 lambda 之路_语法篇
- Java 8 新特性探究(六)泛型的目标类型推断
- Java 8 新特性探究(七)深入解析日期和时间-JSR310
- Java 8 新特性探究(八)精简的 JRE 详解
- Java 8 新特性探究(九)跟 OOM:Permgen 说再见吧
- 总结
- Java 8 新特性探究(十)StampedLock 将是解决同步问题的新宠
- Java 8 新特性探究(十一)Base64 详解
- Java 8 新特性探究(十二)Nashorn :新犀牛
- Java 8 新特性终极指南
- Java 8 新的时间日期库的 20 个使用示例
- Java8 日期时间(Date Time)API 指南
- Java8 本地缓存
- Java 8 的 default 方法能做什么?不能做什么?
- Java 8 的 6 个问题
- Java 8 简明教程
- Java8 集合中的 Lambda 表达式
- Java SE 8 新的时间和日期 API
- 在 Java 8 下更好地利用枚举
- 在 Java 8 中避免 Null 检查
- 鲜为人知的 Java8 特性:泛化目标类型推断
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
Java 8:Lambda 序列化?
最近我一直在考虑为 Tyrus 项目做一个优化处理,允许用户跨越集群向连接到一个 URL 的一部分客户端进行广播。 有很多方法可以达成目标。但自从使用了 JDK 8 后,这个问题简已经变成了我的眼中钉。
为了达到这个目的,我创建了一个简单的单元测试。通过过滤器将它序列化到磁盘上、读取然后执行。我们可以直接或间接地引用它的一个实例字段 VALUE,以此来查出究竟是什么导致了序列化失败。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.NotSerializableException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.function.Predicate;
import org.junit.Test;
public class SerializablePredicateFilterTest {
public String VALUE = "Bob";
public interface SerializablePredicate<T> extends Predicate<T>, Serializable {}
public <T> void filter(SerializablePredicate<T> sp, T value) throws IOException, ClassNotFoundException {
sp.getClass().isLocalClass();
File tempFile = File.createTempFile("labmda", "set");
try (ObjectOutput oo = new ObjectOutputStream(new FileOutputStream(tempFile))) {
oo.writeObject(sp);
}
try (ObjectInput oi = new ObjectInputStream(new FileInputStream(tempFile))) {
SerializablePredicate<T> p = (SerializablePredicate<T>) oi.readObject();
System.out.println(p.test(value));
}
}
}
既然只是为了校对,我们可以让匿名内部类测试失败,因为它总是包含了一个宿主类的对象的引用……
@Test(expected = NotSerializableException.class)
public void testAnonymousDirect() throwsIOException, ClassNotFoundException {
String value = VALUE;
filter(newSerializablePredicate<String>() {
@Override
public boolean test(String t) {
return value.length() > t.length();
}
}, "Bob");
}
对于本地类来说同样如此, 本地类有什么不可以使用呢?
@Test(expected = NotSerializableException.class)
public void testLocalClass() throws IOException, ClassNotFoundException {
class LocalPredicate implements SerializablePredicate<String> {
@Override
public boolean test(String t) {
// TODO Implement this method
return false;
}
}
filter(new LocalPredicate(), "Bobby");
}
一个独立的类当然可以工作,在这个示例中为了方便起见使用了一个嵌套类。
public static class LengthPredicate implements SerializablePredicate<String> {
private String value;
public LengthPredicate(String value) {
super();
this.value = value;
}
public void setValue(String value) {
this.value = value;
}
public String getValue() {
return value;
}
@Override
public boolean test(String t) {
// TODO Implement this method
return false;
}
}
@Test
public void testStaticInnerClass() throws IOException, ClassNotFoundException {
filter(new LengthPredicate(VALUE), "Bobby");
}
我们还是使用 JDK 8,结果证明我的第一个 try 也失败了。但它证明了,通常情况下序列化是非常乐意接受一个 Lambda 表达式的。
@Test(expected = NotSerializableException.class)
public void testLambdaDirect() throws IOException, ClassNotFoundException {
filter((String s) -> VALUE.length() > s.length(), "Bobby");
}
稍微做下改动,拷贝值到一个有效的 final 属性中。瞧,lambda 现在被正确地序列化并且恢复了。
@Test
public void testLambdaInDirect() throws IOException, ClassNotFoundException {
String value = VALUE;
filter((String s) -> value.length() > s.length(), "Bobby");
}
当然,如果 value 是一个简单方法的参数,也可以工作正常。
@Test
public void testLambdaParameter() throws IOException, ClassNotFoundException {
invokeWithParameter(VALUE);
}
private void invokeWithParameter(String value) throws java.lang.ClassNotFoundException, java.io.IOException {
filter((String s) -> value.length() > s.length(), "Bobby");
}
因此答案是肯定的,只要你小心一点就可以对 lambda 进行序列化。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论