ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java函数收集和未经检查的警告

2019-10-24 22:02:14  阅读:263  来源: 互联网

标签:generics type-erasure compiler-warnings java


我已经编写了一个纯函数式的收集类-bag aka multiset-它可以正常工作,但是会在类定义本身以及使用中(尤其是在FBag.make中使用)生成许多未检查分配的警告.据我所知,问题主要来自以下事实:函数集合需要静态工厂方法而不是公共构造函数,并且静态方法无法访问泛型类型.

是否有一种优雅的方法来避免这种情况,还是我只需要硬着头皮,接受这是一个类型擦除问题,并取消警告?

代码如下. (我知道此实现在渐近效率上是无效的.N预计会很小;如果这种变化,我将更改实现.)

import java.util.Collection;
import java.util.Iterator;

public class FBag<E> implements Iterable<E> {
    public static final FBag EMPTY = new FBag<>(null, null);
    private final FBag<E> next;
    private final E val;

    private FBag(E val, FBag<E> next) {
        this.val = val;
        this.next = next;
    }

    public FBag<E> add(E val) {
        return new FBag<>(val, this);
    }

    @Override
    public Iterator<E> iterator() {
        return new Iter<>(this);
    }

    public static FBag make(Collection c) {
        var p = EMPTY;
        for (var a : c) {
            p = p.add(a);
        }
        return p;
    }

    public static FBag make(Object[] c, int from, int to) {
        var p = EMPTY;
        for (var i = from; i < to; i++) {
            p = p.add(c[i]);
        }
        return p;
    }

    public FBag<E> remove(E val) {
        if (this == EMPTY) {
            return this;
        }
        if (this.val == val) {
            return next;
        }
        return new FBag<>(this.val, next.remove(val));
    }

    private static class Iter<E1> implements Iterator {
        private FBag<E1> p;

        Iter(FBag<E1> p) {
            this.p = p;
        }

        @Override
        public boolean hasNext() {
            return p != EMPTY;
        }

        @Override
        public Object next() {
            assert p != EMPTY;
            var r = p.val;
            p = p.next;
            return r;
        }
    }
}

解决方法:

对于静态成员EMPTY,我相信无法使用原始类型.您可以在Collections.EMPTY_LIST中看到相同的内容:

@SuppressWarnings("rawtypes")
public static final List EMPTY_LIST = new EmptyList<>();

@SuppressWarnings("unchecked")
public static final <T> List<T> emptyList() {
    return (List<T>) EMPTY_LIST;
}

因此,您在这里所能做的就是抑制警告:

@SuppressWarnings("rawtypes")
public static final FBag EMPTY = new FBag<>(null, null);

@SuppressWarnings("unchecked")
public static final <T> FBag<T> empty() {
    return (FBag<T>) EMPTY;
}

另一方面,对于静态方法,您可以声明自己的泛型类型变量.

public static <E> FBag<E> make(Collection<E> c) {
    FBag<E> p = empty ();
    for (E a : c) {
        p = p.add(a);
    }
    return p;
}

public static <E> FBag<E> make(E[] c, int from, int to) {
    FBag<E> p = empty ();
    for (int i = from; i < to; i++) {
        p = p.add(c[i]);
    }
    return p;
}

(由于我没有安装Java 10,并且我不想发布未经检查的代码,所以我用显式声明替换了vars).

标签:generics,type-erasure,compiler-warnings,java
来源: https://codeday.me/bug/20191024/1923709.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有