java - 泛型:ClassCastException:java.lang.Object[] 无法转换为

标签 java generics classcastexception

我有一个使用泛型的简单类。

public class ResponseWorkerRunnable<Parameter, Result> implements Runnable {

private final ResponseWorker<Parameter, Result> worker;

/**
 * The parameters for {@link ResponseWorker#doInBackground(Object...)}
 */
private final Parameter[] params;

public ResponseWorkerRunnable(ResponseWorker<Parameter, Result> worker,
        Parameter... params) {

    uiThreadHandler = new Handler(Looper.getMainLooper());

    this.worker = worker;
    this.params = params;
}

@Override
public void run() {

    try {

        Result res = worker.doInBackground(params);
        postResultBack(res);

    } catch (Exception e) {
        postErrorBack(e);
    }

}
}

和我的 ResponseWorker:

public interface ResponseWorker<Parameter, Result> {

    public Result doInBackground(Parameter... param) throws Exception;
}

问题是,我得到了 ClassCastException:

java.lang.ClassCastException: java.lang.Object[] cannot be cast to model.Table[]

我做了这样的事情:

Table t = new Table();
ResponseWorker<Table, SuperTable> worker = ... ;

ResponseWorkerRunnable<Table, SuperTable> r = new ResponseWorkerRunnable<Table, SuperTable>(worker, t);

然后 ResponseWorkerRunnable 将被调度并在将来运行,但出现此异常:

java.lang.ClassCastException: java.lang.Object[] cannot be cast to model.Table[]

在 ResponseWorkerRunnable run() 方法中的这一行:

Result res = worker.doInBackground(params);

我已使用调试器检查 Parameter[] params 字段(在 ResponseWorkerRunnable 中)并将其设置为 Object[1]{Table@4237c0e0}

所以它是一个对象数组,但 ResponseWorker.doInBackground 需要一个 Table 类的数组。

如何正确转换?

Result res = worker.doInBackground((Parameter[]) params);

还有其他想法或暗示可能出现什么问题吗?

------更新------

我使用一个名为 ResponseWorkerExecutor 的单例类将 ResponseWorkerRunnable (带有线程池)调度到

    class ResponseWorkerExecutor {

public static <Parameter, Result> Future<?> submit(
            ResponseWorker<Parameter, Result> responseWorker, Parameter ... params) {

        return INSTANCE.executor
                .submit(new ResponseWorkerRunnable<Parameter, Result>(
                        responseWorker, params));

    }
}

所以在我的代码中我做了这样的事情: 我做了这样的事情:

Table t = new Table();
// ResponseWorker implementation
ResponseWorker<Table, SuperTable> worker = ... ;

// Here is the problem with the args
ResponseWorkerExecutor.submit(worker, t);

最佳答案

由于泛型在 Java 中的工作方式(请阅读此处有关 type erasure 的信息),实际的 Parameter 类在生成的字节码中被 Object 替换,这就是为什么您的 varargs 数组是 Object[] 而不是 Table[]

在这种情况下有一个解决方法应该可行,它涉及对您的代码进行一些更改:

// Pass the actual class object to your Runnable, in this case t.getClass() -> Table.class
ResponseWorkerRunnable<Table, SuperTable> r = new ResponseWorkerRunnable<Table, SuperTable>(worker, t, t.getClass());

然后:

public class ResponseWorkerRunnable<Parameter, Result> implements Runnable {

    private final ResponseWorker<Parameter, Result> worker;

   /**
    * The parameters for {@link ResponseWorker#doInBackground(Object...)}
    */
   private final Parameter[] params;

   private final Class<?> actualClass;

   public ResponseWorkerRunnable(ResponseWorker<Parameter, Result> worker, Parameter... params, Class<?> actualClass) {

        uiThreadHandler = new Handler(Looper.getMainLooper());

        this.worker = worker;
        this.params = params;
        this.actualClass = actualClass;
    }

    @Override
    public void run() {

        try {

            Result res = worker.doInBackground((Parameter[]) Arrays.copyOf(params, params.length, actualClass));
            postResultBack(res);

        } catch (Exception e) {
            postErrorBack(e);
        }
    }
}

它的作用是获取Object[]并将其内容复制到一个新的、真实的Parameter[]中,无论实际的类Parameter是什么> 指的是。然后它使用这个新数组进行可变参数调用。

关于java - 泛型:ClassCastException:java.lang.Object[] 无法转换为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20244957/

相关文章:

java - 如何使用 spring-ws 客户端使用不同的 keystore 调用同一个 webservice

generics - FSharpPlus divRem - 它是如何工作的?

Django:与 Contenttypes 的通用一对多关系

java.lang.ClassCastException : java. lang.String JSON Tokener android

java - HeaderElement1_1Impl ClassCastException Java 使用 JDK 而不是 saaj-impl

java - 运行时 Java jar 返回 java.lang.NoClassDefFoundError

java - 替代 Java 选择器实现

java - 每个程序运行时实现一个静态计数器

c# - 创建IQueryable <T>的通用过滤器,其中该过滤器使用ISomeInterface中定义的属性

java - 如何将行数据从 1 个 JTable 移动到另一个 JTable?