Enum类是Serializable,因此使用枚举序列化对象没有问题.另一种情况是class具有java.util.Optional类的字段.在这种情况下,抛出以下异常:java.io.NotSerializableException:java.util.Optional
如何处理这些类,如何序列化它们?是否可以将此类对象发送到远程EJB或通过RMI?
这是一个例子:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Optional;
import org.junit.Test;
public class SerializationTest {
static class My implements Serializable {
private static final long serialVersionUID = 1L;
Optional<Integer> value = Optional.empty();
public void setValue(Integer i) {
this.i = Optional.of(i);
}
public Optional<Integer> getValue() {
return value;
}
}
//java.io.NotSerializableException is thrown
@Test
public void serialize() {
My my = new My();
byte[] bytes = toBytes(my);
}
public static <T extends Serializable> byte[] toBytes(T reportInfo) { …Run Code Online (Sandbox Code Playgroud) 我遇到过使用方法引用但没有使用lambdas的问题.该代码如下:
(Comparator<ObjectNode> & Serializable) SOME_COMPARATOR::compare
Run Code Online (Sandbox Code Playgroud)
或者,与lambda,
(Comparator<ObjectNode> & Serializable) (a, b) -> SOME_COMPARATOR.compare(a, b)
Run Code Online (Sandbox Code Playgroud)
从语义上讲,它是完全相同的,但实际上它是不同的,因为在第一种情况下,我在其中一个Java序列化类中得到一个异常.我的问题不是关于这个例外,因为实际的代码是在一个更复杂的上下文中运行的,这个上下文已经被证明在序列化方面有奇怪的行为,所以如果我提供更多的细节,它会让它太难以回答.
我想要了解的是这两种创建lambda表达式的方法之间的区别.
由于已经知道它很容易地添加序列化支持lambda表达式时,目标接口已经不继承Serializable,只是喜欢(TargetInterface&Serializable)()->{/*code*/}.
我问,是一种反其道而行之,明确删除支持串行当目标接口不继承Serializable.
由于您无法从类型中删除接口,因此基于语言的解决方案可能看起来像(@NotSerializable TargetInterface)()->{/* code */}.但据我所知,没有这样的解决方案.(纠正我,如果我错了,这将是一个完美的答案)
即使在类实现时拒绝序列化是Serializable过去的合法行为,并且程序员控制下的类,模式看起来如下:
public class NotSupportingSerialization extends SerializableBaseClass {
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
throw new NotSerializableException();
}
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException {
throw new NotSerializableException();
}
private void readObjectNoData() throws ObjectStreamException {
throw new NotSerializableException();
}
}
Run Code Online (Sandbox Code Playgroud)
但是对于lambda表达式,程序员没有对lambda类的控制.
为什么有人会费心去除支持?好吧,除了生成包含Serialization支持的更大代码之外,它还会产生安全风险.请考虑以下代码:
public class CreationSite {
public static void main(String... arg) {
TargetInterface f=CreationSite::privateMethod;
} …Run Code Online (Sandbox Code Playgroud) 在那里有一个内部问题,为什么java匿名类不能同时实现和子类?或者只是因为语法?
如果我使用新语法获取方法引用:
anObject::aMethod
Run Code Online (Sandbox Code Playgroud)
我总是得到同一个对象吗?也就是说,我可以相信对同一方法的两个引用是相同的吗?
例如,我很乐意知道是否计划将它们用作Runnable我可以添加和删除的回调:
someLibrary.addCallback(anObject::aMethod)
// later
someLibrary.removeCallback(sameObject::sameMethod)
Run Code Online (Sandbox Code Playgroud)
这是否需要在Runnable变量中保存引用以保持其稳定?
我正在查看Map界面的Java源代码,并遇到了这一小段代码:
/**
* Returns a comparator that compares {@link Map.Entry} in natural order on value.
*
* <p>The returned comparator is serializable and throws {@link
* NullPointerException} when comparing an entry with null values.
*
* @param <K> the type of the map keys
* @param <V> the {@link Comparable} type of the map values
* @return a comparator that compares {@link Map.Entry} in natural order on value.
* @see Comparable
* @since 1.8
*/
public static <K, …Run Code Online (Sandbox Code Playgroud) 我可以使用以下语法序列化lambda:
Runnable r = (Runnable & Serializable) () -> System.out.println("");
try (ObjectOutput oo = new ObjectOutputStream(new ByteArrayOutputStream())) {
oo.writeObject(r);
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我从客户端代码收到lambda并且它没有被正确转换,我就无法序列化它.
如何r在不更改其定义的情况下序列化以下内容:
Runnable r = () -> System.out.println("");
Run Code Online (Sandbox Code Playgroud)
我试图序列化"派生"对象:
Runnable r1 = (Runnable & Serializable) r::run;
Runnable r2 = (Runnable & Serializable) () -> r.run();
Run Code Online (Sandbox Code Playgroud)
但在每种情况下,都oo.writeObject(rxxx);失败了NotSerializableException.
我正在编写一个可序列化的类,它带有几个参数,包括Function:
public class Cls implements Serializable {
private final Collection<String> _coll;
private final Function<String, ?> _func;
public Cls(Collection<String> coll, Function<String, ?> func) {
_coll = coll;
_func = func;
}
}
Run Code Online (Sandbox Code Playgroud)
func存储在成员变量中,因此需要可序列化.如果它们被分配的类型是可序列化的,则 Java lambdas 是可序列化的.Function如果使用lambda创建,那么确保我在构造函数中传递的最佳方法是可序列化的?
创建一个SerializableFunction类型并使用它:
public interface SerializableFunction<F, R> implements Function<F, R>, Serializable {}
....
public Cls(Collection<String> coll, SerializableFunction<String, ?> func) {...}
Run Code Online (Sandbox Code Playgroud)
问题:
coll和func参数之间存在不匹配,在func签名中声明为可序列化,但coll不是,但两者都需要可序列化才能工作.Function可序列化.在构造函数上使用类型参数:
public <F extends Function<String, …Run Code Online (Sandbox Code Playgroud)我正在研究Comparator#comparing()JDK 1.8 的源代码,并且lambda的渲染对我来说是一个惊喜:
//declaration
{
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable) // <- this cast here
(c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}
Run Code Online (Sandbox Code Playgroud)
看完之后
如果指定的函数也是可序列化的,则返回的比较器是可序列化的.
和一些玩代码,我弄清楚为什么这个工作,以及为什么如果演员不同,它将无法工作.
我的问题是:这个多重铸造是什么(A & B)?
通过谷歌搜索java multiple cast我发现只有多个使用铸造(A)(B).是否有关于在JDK中添加此内容的文章1.8?
今天我在jdk8源代码中发现了奇怪的代码,无法找到任何解释.
static final Comparator<ChronoLocalDate> DATE_ORDER =
(Comparator<ChronoLocalDate> & Serializable) (date1, date2) -> {
return Long.compare(date1.toEpochDay(), date2.toEpochDay());
};
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释为什么和Serializable出<>?
提供文档链接会很棒.
链接到源:AbstractChronology