相关疑难解决方法(0)

如何安全地序列化lambda?

尽管可以在Java 8中序列化lambda,但强烈建议不要这样做.甚至不鼓励对内部类进行序列化.给出的原因是lambdas可能不会在另一个JRE上正确地反序列化.然而,这并不意味着这有一个办法可以安全的序列化拉姆达?

例如,假设我将类定义为:

public class MyClass {
    private String value;
    private Predicate<String> validateValue;

    public MyClass(String value, Predicate<String> validate) {
        this.value = value;
        this.validateValue = validate;
    }

    public void setValue(String value) {
        if (!validateValue(value)) throw new IllegalArgumentException();
        this.value = value;
    }

    public void setValidation(Predicate<String> validate) {
        this.validateValue = validate;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我像这样声明了类的实例,我不应该序列化它:

MyClass obj = new MyClass("some value", (s) -> !s.isEmpty());
Run Code Online (Sandbox Code Playgroud)

但是如果我像这样创建了一个类的实例呢:

// Could even be a static nested class
public class IsNonEmpty …
Run Code Online (Sandbox Code Playgroud)

java lambda serialization java-8

8
推荐指数
1
解决办法
4287
查看次数

lambda表达式序列化的安全风险是什么?

刚刚介绍Streams和Java 8 Lambda功能,以及对其他不言自明的Oracle doc Lambda Expressions的最后评论:

如果lambda表达式的目标类型及其捕获的参数是可序列化的,则可以序列化它.但是,与内部类一样,强烈建议不要对lambda表达式进行序列化.

检查这一点我发现了SO问题

如何序列化lambda?

OP处理来自客户端代码的序列化lambda表达式.

如果我有一个互联网服务和参数之一是一个lambda表达式,现在看来,这可能包含恶意代码,可以做这样的事情的文件系统访问权限,或导致堆栈溢出 - 所以这将是非常愚蠢的信任它.

我是否过度夸大了安全风险,或者序列化表达式可以包含什么限制?

java lambda serialization java-8

8
推荐指数
1
解决办法
469
查看次数

相交类型是什么类型?

请考虑以下使用交叉类型的能力的代码,它是在Java 8中添加的:

private <E, T extends List<E> & RandomAccess> void takeList(T list) {

}

private void fakingRandomAccess() {
    List<Integer> linkedList = new LinkedList<>();
    takeList((List<Integer> & RandomAccess)linkedList);
}
Run Code Online (Sandbox Code Playgroud)

我已经制定了一个takeList方法,它只采用具有(接近)恒定访问时间的列表,无论出于何种原因,但我可以想象有些情况确实需要这样做.

路过的ArrayList<E>进入方法应该工作得很好,但是通过交叉型也可以传递一个LinkedList<E>假装它有固定的访问时间.

现在我的问题是:

  • 有没有办法存储(List<Integer> & RandomAccess)linkedList在指定类型的对象中?
  • 我可以使用类型交叉点来简化takeList方法吗?

java java-8

7
推荐指数
1
解决办法
1235
查看次数

使用CompletableFuture处理Java 8供应商异常

考虑以下代码 -

public class TestCompletableFuture {

    BiConsumer<Integer, Throwable> biConsumer = (x,y) -> {
        System.out.println(x);
        System.out.println(y);
    };

    public static void main(String args[]) {
        TestCompletableFuture testF = new TestCompletableFuture();
        testF.start();      
    }

    public void start() {
        Supplier<Integer> numberSupplier = new Supplier<Integer>() {
            @Override
            public Integer get() {
                return SupplyNumbers.sendNumbers();                     
            }
        };
        CompletableFuture<Integer> testFuture = CompletableFuture.supplyAsync(numberSupplier).whenComplete(biConsumer);         
    }       
}

class SupplyNumbers {
    public static Integer sendNumbers(){
        return 25; // just for working sake its not  correct.
    }
}
Run Code Online (Sandbox Code Playgroud)

以上的事情很好.但是sendNumbers也可以在我的情况下抛出一个检查过的异常,例如:

class SupplyNumbers {
    public …
Run Code Online (Sandbox Code Playgroud)

java exception java-8 completable-future

7
推荐指数
3
解决办法
1万
查看次数

带序列化的Java 8 Lambda表达式

在我们的Web应用程序项目中,我们使用Redis来管理会话.为了支持它,我们正在序列化将存储在会话中的任何对象.

例如,我们使用DTO来保存用于在屏幕上显示的bean数据.即使DTO内部有任何其他对象(组合),我们也必须序列化它,否则我们得到NotSerializableException.

当我创建一个匿名内部类来实现Comparator下面这样的时候,我遇到了一个问题:

Collections.sort(people, new Comparator<Person>() {
    public int compare(Person p1, Person p2) {
        return p1.getLastName().compareTo(p2.getLastName());
    }
});
Run Code Online (Sandbox Code Playgroud)

上面的代码抛出了NotSerializableException,我通过创建一个实现Comparator以及Serializable接口的类来解决它.问题是,它被抛入JSP使用此DTO 的页面内.我不得不做很多调试才能找到实际问题.

但是现在,我想知道更改上面的代码以使用如下的Lambda表达式:

Collections.sort(people, (p1, p2) -> p1.getLastName().compareTo(p2.getLastName()));
Run Code Online (Sandbox Code Playgroud)

但是,我担心可能会发生同样的异常.Lambda表达式是否在内部创建对象?

java lambda serialization redis

6
推荐指数
1
解决办法
3653
查看次数

是否可以引用Java 8中可序列化的实例方法?

我想知道对特定类型的任意对象的实例方法的引用是否可序列化?

例:

public class MyClass {
    public void foo() {
        System.out.println("Serializable");
    }
}
Run Code Online (Sandbox Code Playgroud)

SerializableConsumer

@FunctionalInterface
public interface SerializableConsumer<T> extends Consumer<T>, Serializable {
}
Run Code Online (Sandbox Code Playgroud)

和领域是:

SerializableConsumer<MyClass> serializableMethod = MyClass::foo;
Run Code Online (Sandbox Code Playgroud)

EDITED

java-8

6
推荐指数
1
解决办法
1003
查看次数

使用&的Strange Java强制语法

(实际上,这个问题与lambdas没有直接关系,但是对于使用边界的强制转换,所以标记为重复的问题并没有提供这个问题的答案.你会在这里找到我的问题的答案:我应该如何为Java转换具有多个边界的泛型?)

就在最近,我参加了SW工艺会议.在其中一个讨论的例子中,我遇到了一些这样的演员,它似乎是自Java 8以来的有效Java.

Object aTest = (String & CharSequence) "test";
Run Code Online (Sandbox Code Playgroud)

我的问题:有人可以告诉我这背后的成语以及它究竟能为我们做些什么吗?该示例的演示者无法解释它,我没有找到任何提及(我甚至不知道它的名称).

除了Oleksandr之外,我还要在这里提出另一个答案,因为这个问题已被标记为重复,因此被锁定.

与此同时,我能够构建一个(人为的)用例,只是为了明确这个想法.

假设我们有泛型方法foo(),它的唯一参数是通用的,而type参数有两个上限(反对ComparableSerializable):

public static <T extends Comparable & Serializable> void foo(T t) {
    System.out.println(t);
}
Run Code Online (Sandbox Code Playgroud)

进一步假设,我们有一个类AClass,实现ComparableSerializable

public class AClass implements Comparable, Serializable {
    @Override
    public int compareTo(Object other) {
        return 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

进一步假设设计的部分,我们有一个AClass对象instance,它被分配给一个类型的变量Object:

Object instance = new AClass();
Run Code Online (Sandbox Code Playgroud)

如果,在代码的另一个地方,我们想要传递instancefoo(),并且我们不知道动态类型 …

java casting bounded-types type-bounds java-8

6
推荐指数
1
解决办法
318
查看次数

为什么Java 8的Comparator.comparing()将返回值强制转换为Serializable?

来自JDK8的Comparator.java:

public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
        Function<? super T, ? extends U> keyExtractor)
{
    Objects.requireNonNull(keyExtractor);
    return (Comparator<T> & Serializable)
        (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}
Run Code Online (Sandbox Code Playgroud)

请注意,return语句带有一个有趣的强制转换前缀: (Comparator<T> & Serializable)

我已经意识到并且(我认为)理解:

  • &泛型类型限制的运算符(并且可以在此推断其用途),
  • Serializable接口.

然而,在演员阵容中一起使用对我来说是令人困惑的.

& Serializable如果返回类型不需要它的目的是什么?

我不明白这个意图.

对欺骗/关闭请求的后续行动:这个问题如何序列化lambda?不回答问题.我的问题特别注意到返回类型没有提及Serializable,因此我的困惑的来源.

java casting

5
推荐指数
1
解决办法
554
查看次数

如何使函数Serializable以通用方式

我知道我们可以将函数转换为Serializable需要它的位置.

但是,我想将此转换移动到通用方法,以使使用代码更简洁.我无法创建这样的方法.

我的具体问题是下面的地图不是Serializable:

final Map<MyObject, String> map =
        new TreeMap<>(Comparator.comparing(MyObject::getCode));
Run Code Online (Sandbox Code Playgroud)

我可以通过使用:

final Map<MyObject, String> map =
        new TreeMap<>(Comparator.comparing((Function<MyObject, String> & Serializable) MyObject::getCode));
Run Code Online (Sandbox Code Playgroud)

但我希望能够做到这样的事情:

final Map<MyObject, String> map =
        new TreeMap<>(Comparator.comparing(makeSerializable(MyObject::getCode)));

public static <T, U> Function<T, U> makeSerializable(Function<T, U> function) {
    return (Function<T, U> & Serializable) function;
}
Run Code Online (Sandbox Code Playgroud)

对于编译器这很好,但在运行时,我得到一个ClassCastException:

java.lang.ClassCastException: SerializableTest$$Lambda$1/801197928 cannot be cast to java.io.Serializable
Run Code Online (Sandbox Code Playgroud)

我也尝试了以下替代方案,但没有成功:

// ClassCastException
public static <T extends Serializable, U extends Serializable> Function<T, U> makeSerializable(Function<T, U> …
Run Code Online (Sandbox Code Playgroud)

java generics lambda comparator java-8

4
推荐指数
1
解决办法
592
查看次数

为什么大多数 Eclipse 集合类型都是可序列化的?

我在这里寻找设计原理。

我当然可以理解使集合类可序列化,尽管 JCF 不这样做。然而,ProcedureIntProcedure等接口尤其是存在的主要候选者Serializable,因为无论如何它们通常都是匿名的。

制作这些接口Serializable违背了 Josh Bloch 的建议,即接口应该很少扩展Serializable[1]。

我可能需要更新我的 Eclipse 首选项,以免为每个匿名 发出串行 uid 警告Procedure

[1] 有效的 Java 第二版。第 291 页

java serializable eclipse-collections

3
推荐指数
1
解决办法
471
查看次数

lambda用于接口实现时,“无效的lambda反序列化”

我有一个带有lambda表达式的检票口项目。在用户单击后退按钮的一页上,我的应用程序崩溃:

java.lang.IllegalArgumentException: Invalid lambda deserialization
at x.y.z.MyPage$3.$deserializeLambda$(MyPage.java:1)
Run Code Online (Sandbox Code Playgroud)

在页面类(我返回的地方)中,我使用lambda表达式实现此接口:

public interface Localizator extends Serializable {
    String getLocalizedString(String key);
}
Run Code Online (Sandbox Code Playgroud)

和lambda:

protected void someMethod() {
    localize((String key) -> getString(key));
}
Run Code Online (Sandbox Code Playgroud)

当我将lambda更改为匿名类时,一切正常。在这种情况下应如何使用lambda?

信封:Java 1.8.0_25,Netbeans 8.0.2,Wicket 6.17.0。

编辑:这是带有lambda的真实(但简化)方法:

@Override
protected DataLoader createDataLoader() {

    return new DataLoader(){

        @Override
        public List loadData() {
            ...
        }

        @Override
        public List convertToTableRows(List data) {
            return Converter.asRowList(
                data, 
                (Record record) -> {...}, // this lambda is OK
                (String key) -> getString(key)); // this lambda is crashing
        }

        @Override
        public List …
Run Code Online (Sandbox Code Playgroud)

lambda wicket java-8

1
推荐指数
1
解决办法
2815
查看次数