0

次のクラスをコンパイルすると (ここで入手可能。1 つのクラスで問題を再現するためにメイン メソッドが追加されています)、IntelliJ または maven コマンド ラインから次のコンパイラ警告が表示されます。

java: /Users/luigi/var/src/owner/src/test/java/org/aeonbits/owner/multithread/ThreadBase.java uses unchecked or unsafe operations.
java: Recompile with -Xlint:unchecked for details.

次に、詳細を確認するために -Xlint:unchecked を maven に追加したところ、次のようになりました。

[WARNING] /Users/luigi/var/src/owner/src/test/java/org/aeonbits/owner/multithread/ThreadBase.java:[74,45] unchecked conversion
  required: java.util.List<java.lang.Throwable>
  found:    java.util.List

クラスのソースは次のとおりです (メインは単一のクラスで問題を再現するために追加されています)。

package org.aeonbits.owner.multithread;

import org.aeonbits.owner.Config;
import org.aeonbits.owner.UtilTest.MyCloneable;

import java.util.ArrayList;
import java.util.List;

import static org.aeonbits.owner.UtilTest.debug;

abstract class ThreadBase<T extends Config> extends Thread implements MyCloneable {
    private static long counter = 0;
    final long uniqueThreadId = ++counter;
    final T cfg;
    final Object lock;
    final int loops;
    final List<Throwable> errors = new ArrayList<Throwable>();

    ThreadBase(T cfg, Object lock, int loops) {
        this.cfg = cfg;
        this.lock = lock;
        this.loops = loops;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public void run() {
        synchronized (lock) {
            try {
                lock.wait();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return;
            }
        }
        for (int i = 0; i < loops; i++) {
            debug("%s[%d] started loop #%d.\n", getClass().getName(), uniqueThreadId, i);
            try {
                execute();
            } catch (Throwable throwable) {
                debug("%s[%d] thrown an error in loop #%d.\n", getClass().getName(), uniqueThreadId, i);
                errors.add(throwable);
            }
            yield();
            debug("%s[%d] completed loop #%d.\n", getClass().getName(), uniqueThreadId, i);
        }
    }

    abstract void execute() throws Throwable;

    public List<Throwable> getErrors() {
        return errors;
    }

    public static void main(String[] args) {
        ThreadBase t = new ThreadBase(null, new Object(), 10) {
            @Override
            void execute() throws Throwable {

            }
        };
        List<Throwable> errors = t.getErrors();
        //                                  ^ compiler reports the warning here!
    }
}

追加の詳細:

$ mvn --version
Apache Maven 3.0.4 (r1232337; 2012-01-17 09:44:56+0100)
Maven home: /Users/luigi/opt/apache-maven-3.0.4
Java version: 1.7.0_25, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "10.8.4", arch: "x86_64", family: "mac"

pom.xml では、ライブラリが jdk 1.5 以上を対象としているため、compiler.source と compiler.target 1.5 を追加しました。

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                    <compilerArgument>-Xlint:unchecked</compilerArgument>
                </configuration>
            </plugin>
        </plugins>
    </pluginManagement>

ここで何が悪いのか誰か説明してもらえますか?

私にとっては、 t.getErrors() がリストを返すので意味がありません:

List<Throwable> errors = t.getErrors();

ここで何が問題なのですか?!?

4

1 に答える 1

5

あなたtは の生の型ですThreadBase

ThreadBase t = new ThreadBase(null, new Object(), 10) {

つまり、 method などの無関係なものも含め、すべてのジェネリックが削除されますgetErrors

public List getErrors() {

次に、その警告なしに anListを aに割り当てることはできません。List<Throwable>

その警告を排除したい場合は、生のインスタンスを持ってはいけません。ThreadBase初期化時に型パラメーターを指定します。たとえば、次のようになります。

ThreadBase<Config> t = new ThreadBase<Config>(null, new Object(), 10) {

getErrors次に、既存のコードで正常に呼び出すことができるはずです。

List<Throwable> errors = t.getErrors();
于 2013-06-25T21:40:49.447 に答える