繁体   English   中英

难以控制的投放警告

[英]Difficult unchecked cast warnings

我正在尝试清理一些旧代码,并尝试消除一些unchecked cast强制转换警告。

我将给出警告的代码提取到下面的可编译程序中。 请注意,我删除了许多代码以使其更小,因此所有这些代码可能都不完全有意义。 它可以编译,但是运行它不会做任何事情。

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipInputStream;

public class GenericsTest {

    public static void main(String[] args) throws IOException {
        Reader reader = new Reader();
        List<String> stringEntries = reader.readAll(StringEntry.class);
    }

    public static class Reader {

        public <T> ZipInputStream getInputStream(String fileName) throws ZipException, FileNotFoundException {
            return new ZipInputStream(new FileInputStream(fileName));//_file.getInputStream(_paths.get(fileName));
        }

        public <T, TEntry extends Entry<T>> List<T> readAll(Class<TEntry> type) throws IOException {
            List<T> list = new ArrayList<T>();
            List<TEntry> entries = createEntries(type);
            for (TEntry entry : entries) {
                list.add(read(entry));
            }
            return list;
        }

        public <T> T read(Entry<T> entry) throws IOException {
            ZipInputStream is = null;
            try {
                //is = _archive.getInputStream(entry.getName());
                return entry.read(is);
            } finally {
                if (is != null) {
                    is.close();
                }
            }
        }

        public <TEntry extends Entry> List<TEntry> createEntries(Class<TEntry> type) throws ZipException {
            List<TEntry> entries = new ArrayList<TEntry>();
            List<String> paths = new ArrayList<String>();//getPaths(type);
            for (String path : paths) {
                entries.add(createEntry(type, path));
            }
            return entries;
        }

        public <TEntry extends Entry> TEntry createEntry(Class<TEntry> type, String folder) {
            if (StringEntry.class.equals(type)) {
                return (TEntry) new StringEntry(folder);
            } else if (IntegerEntry.class.equals(type)) {
                return (TEntry) new IntegerEntry(folder);
            }
            throw new IllegalArgumentException("Unknown type: " + type);
        }
    }

    public static abstract class Entry<T> extends ZipEntry {

        private T _data;

        public Entry(T data, String folder, String name) {
            super(folder + "/" + name);
            _data = data;
        }

        protected abstract T read(InputStream is) throws IOException;
    };

    public static class StringEntry extends Entry<String> {

        public StringEntry(String folder) {
            super("Hallo world!", folder, "StringEntry");
        }

        @Override
        protected String read(InputStream is) throws IOException {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    };

    public static class IntegerEntry extends Entry<Integer> {

        public IntegerEntry(String folder) {
            super(42, folder, "IntegerEntry");
        }

        @Override
        protected Integer read(InputStream is) throws IOException {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    };
}

编译以上代码会给出以下警告

GenericsTest.java:57: warning: [unchecked] unchecked cast 
found: GenericsTest.StringEntry
required: TEntry
                return (TEntry) new StringEntry(folder);
GenericsTest.java:59: warning: [unchecked] unchecked cast 
found: GenericsTest.IntegerEntry
required: TEntry
                return (TEntry) new IntegerEntry(folder);
2 warnings

改变中

public <TEntry extends Entry> TEntry createEntry...

public <TEntry extends Entry<T>> TEntry createEntry...

给出编译器错误( cannot find symbol: class T )。

我不想对代码进行太多更改,因为它可以正常工作,那么如何在代码更改最少的情况下修复(而不是隐藏)警告?

如果要使用多个通用参数,则需要在参数列表中指定它。 你可以试试这个吗?

public <T, TEntry extends Entry<T>> TEntry createEntry(...

更新

我花了一些时间来处理这个问题,并使用了那些不错的类对象:

    public <T, TEntry extends Entry<T>> List<TEntry> createEntries(Class<TEntry> type) throws ZipException {
        List<TEntry> entries = new ArrayList<TEntry>();
        List<String> paths = new ArrayList<String>();//getPaths(type);
        for (String path : paths) {
            entries.add(createEntry(type, path));
        }
        return entries;
    }

    public <T, TEntry extends Entry<T>> TEntry createEntry(Class<TEntry> type, String folder) {
        if (StringEntry.class.equals(type)) {
            return type.cast(new StringEntry(folder));
        } else if (IntegerEntry.class.equals(type)) {
            return type.cast(new IntegerEntry(folder));
        }
        throw new IllegalArgumentException("Unknown type: " + type);
    }
}

您已经将Class对象传递到方法中,只需使用Class.cast()

public <TEntry extends Entry<?>> TEntry createEntry(Class<TEntry> type, String folder) {
    if (StringEntry.class.equals(type)) {
        return type.cast(new StringEntry(folder));
    } else if (IntegerEntry.class.equals(type)) {
        return type.cast(new IntegerEntry(folder));
    }
    throw new IllegalArgumentException("Unknown type: " + type);
}

上面的更改使您的代码在没有警告的情况下进行编译。

另外, getInputStream()签名中的<T>可能不是必需的。

对于旧代码的恕我直言,使其具有通用友好性可以是一种很好的体验,特别是如果您有大量的代码基础...由于可能已部署了此代码,您是否不考虑采用迭代方法?

用迭代的方法,我的意思是...得到所有警告,并通过@SuppressWarning和TODO注释将其消除,然后,随着时间的流逝,每次您需要更改代码时,如果偶然发现了TODO, ,然后更改它即可...

我只是说,以防您刚迁移到Java 5并收到数千条警告。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM