创建泛型类列表

时间:2017-12-28 19:09:27

标签: java generics java-7

我有一个实用程序方法,可以从某个对象中创建一个单元素列表:

public static final <T> List<T> list(T t) {
    final List<T> rv = new ArrayList<>();
    rv.add(t);
    return rv;
}

我还有一个接受List<Class<?>>类型参数的方法。所以我必须创建一个这种类型的对象。这是我尝试做的事情:

final Class<?> aClass = Integer.class;
final List<Class<?>> trivialListOfClasses = list(aClass);

...这失败了:

[javac] /some/path/Foo.java:41: error: incompatible types
[javac]             final List<Class<?>> trivialListOfClasses = list(aClass);
[javac]                                                                  ^
[javac]   required: List<Class<?>>
[javac]   found:    List<Class<CAP#1>>
[javac]   where CAP#1 is a fresh type-variable:
[javac]     CAP#1 extends Object from capture of ?
[javac] 1 error

实现上述目标的正确方法是什么?我理解Java泛型不变的部分,但究竟发生了什么?

3 个答案:

答案 0 :(得分:5)

能够在-source 7 -target 7上使用javac 1.8.0_144进行复制。

如果您只打算从列表中取出内容,那么有效的一件事就是使用? extends Class<?>

Class<?> aClass = Integer.class;
List<? extends Class<?>> trivialListOfClasses = list(aClass);
Class<?> bClass = trivialListOfClasses.get(0); // works
// trivialListOfClasses.add(String.class); // doesn't work, though

还可以在list

的调用中手动提供泛型类型
Class<?> aClass = Integer.class;
List<Class<?>> trivialListOfClasses = Util.<Class<?>>list(aClass);
Class<?> bClass = trivialListOfClasses.get(0); // works
trivialListOfClasses.add(String.class); // also works

似乎编译器无法将List<Class<?>>的通配符类型与list自己返回的通配符类型进行协调。

答案 1 :(得分:1)

final List<Class<?>> trivialListOfClasses = list(aClass);

适用于Java 1.8和9

final List<?> trivialList = list(aClass);
@SuppressWarnings("unchecked")
final List<Class<?>> trivialListOfClasses = (List<Class<?>>) trivialList;

是1.7的解决方法。似乎1.7编译器无法验证list(T t)返回的类型是否依赖于T

答案 2 :(得分:-2)

有一个oracle javadoc我不太确定,但它适用于java 8.而9只是出来了;)

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QGridLayout, QDoubleSpinBox,\
    QLabel


class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):

        button = QPushButton('Button', self)
        button.move(50, 50) 

        self.sideWindowTest = sideWindowTest(self)
        button.clicked.connect(lambda: self.sideWindowTest.setupWindow())

        self.setGeometry(300, 300, 300, 220)
        self.setWindowTitle('Main')

        self.show()

class sideWindowTest(object):

    myWdg = None

    def __init__(self, parent):
        super().__init__()
        self.viewer = parent

    def initiateMenuBar(self):
        self.myWdg.setWindowTitle('Phasing')
        self.myWdg.setWindowModality(Qt.ApplicationModal)
        MenuBar = QVBoxLayout()
        self.labels = {
            'phase 0': QLabel('Phase 0', self.myWdg),
        }
        self.inputs = {
            'phase 0': QDoubleSpinBox(self.myWdg),
        }

        for i in self.inputs.values():
            i.installEventFilter(self.myWdg)

        self.inputs['phase 0'].setValue(0)

        MenuBar.addWidget(self.labels['phase 0'])
        MenuBar.addWidget(self.inputs['phase 0'])
        MenuBar.addStretch(1)

        return MenuBar

    def setupWindow(self):

        if not self.myWdg:
            self.myWdg = QWidget()

            MenuBar = self.initiateMenuBar()

            grid = QGridLayout()
            grid.setSpacing(10)        

            grid.addLayout(MenuBar, 0, 0, 1, 2)
            self.myWdg.setLayout(grid)
            self.myWdg.setGeometry(0, 0, 400, 100)

        self.myWdg.show()
        self.myWdg.activateWindow() 


if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())
相关问题