如何在没有编译器警告的情况下将任意数量的参数化函数传递给构造函数



我有一个Test类和一个Writer类。

Writer类除了将字符串写入StringBuilder之外什么也不做。也允许有"变压器">。这意味着,在Writer类的构造函数中,您可以传递任意数量的lambda函数来为您正在编写的字符串添加额外的处理。

例如:String::toLowerCase

我希望能够将多个"转换器">传递给写入器的构造函数。

我有下面的代码:

///Writer Class   Writer(Function<String, String>... someFunctions) {
abstract class Writer {
  Function<String, String>[] functions;
  Writer(Function<String, String>... someFunctions) {
    functions = someFunctions;
  }
}
///Test Class
    @Test
    default void WriterTestWriteThere() throws IOException {
        Writer writer = createWriter();
        writer.write("There");
        writer.close();
        assertEquals("There", getContents());
    }
    @Test
    default void WriterTestTwoTransformerFunctions() throws IOException {
        Writer writer = createWriter(
                text -> text.replaceAll("sometext", "s*****"),
                String::toUpperCase
        );
        writer.write("This is somethext!");
        writer.close();
        assertEquals("THIS IS S*****!", getContents());
    }

但是,编译器会发出多个警告 .

Possible heap pollution from parameterized vararg type - Writer类的构造函数的错误信息。

Unchecked generics array creation for varargs parameter -创建Writer实例时Test类的错误信息。

我不能使用@ safevargs或@SuppressWarnings

我已经在网上到处看了,但是不能得到一个关于为什么要创建这些警告的可靠答案,除了Java编译器不喜欢将参数化的参数传递到列表中。这就提出了我的问题。

我可以用什么来修复它?

我需要能够将多个函数传递到writer类中,以根据这些函数的需要转换文本,并且没有警告。除了Function之外,我还尝试过其他Java实用程序类,但我似乎找不到我需要的。

我不能使用@ safevargs或@SuppressWarnings

你可能知道,数组泛型不能很好地结合在一起。

数组是协变的,即方法指定Number[] -您可以将Integer[], Double[], BigInteger[]等作为参数传递。

泛型是不变的,即如果声明的参数是List<Number> -你只能传递List<Number>

当你向方法传递一个参数时,该方法期望varargs它们将被一个数组包装。因此,当您混合使用变量和泛型时,编译器无法确保类型安全,并且由于无法验证参数的类型是否匹配,因此它会警告您可能存在堆污染。

你必须消除创建泛型数组的需要。

最好的选择是在传递给Writer的构造函数之前将所有函数组合成一个函数。

Function<String, String> f1 = String::toUpperCase;
Function<String, String> f2 = text -> text.replaceAll("somethext", "s*****");
Function<String, String> f3 = text -> text.replaceAll("\p{Punct}", "&");
Function<String, String> combined = f1.andThen(f2).andThen(f3);

Writer应该有一个类型为Function<String, String>的字段,而不是一个函数数组。

public class Writer {
    private Function<String, String> function;
    public Writer(Function<String, String> function) {
        this.function = function;
    }
}

最新更新