gpt4 book ai didi

java - 将特定于类和特定于方法的泛型封装在一种类型中

转载 作者:搜寻专家 更新时间:2023-10-30 20:02:29 26 4
gpt4 key购买 nike

假设我需要一个绑定(bind)到通用 Comparable 类型的类:

class A<T extends Comparable<T>> {

// this is just an example of usage of T type
List<T> comparables;

int compareSomething(T smth) {
return comparables.get(0).compareTo(smth);
}
}

该类有一个在签名中带有自己的泛型的方法:

<V> Future<V> submit(Callable<V> task) {
return someExecutorService.submit(task);
}

现在,是否有可能将 submit 方法的输入限制为仅接受同样实现了 TCallables?我首先尝试了这个:

<V, W extends T & Callable<V>> Future<V> submit(W task) {
if(compareSomething(task) != 0)
throw new RuntimeException("");
return someExecutorService.submit(task);
}

但发现这是不可能的(由于描述的原因 here )。有没有优雅的可能绕过它?


编辑:我能想到的一个丑陋的可能性是将封装拆分为两种不同的类型并在 submit 中传递一个对象对:

class A<T extends Comparable<T>> {

// this is just an example of usage of T type
List<T> comparables;

int compareSomething(T smth) {
return comparables.get(0).compareTo(smth);
}
<V> Future<V> submit(Callable<V> task, T comparable) {
if(compareSomething(comparable) != 0)
throw new RuntimeException("");
return someExecutorService.submit(task);
}
}

主要缺点是方法签名变得更加复杂,而且我需要一些 TCallable 的一对一映射以用于后面的代码.也许有人可以建议一种以适当方式解决它的模式?..


编辑,进行两次:让我简要解释一下我要实现的目标。我正在研究能够执行某种特殊任务调度的自定义线程池实现。为此,此服务仅接受一种特殊类型的 Callable 任务。这些 Callable 必须实现一个类似于 Comparable 的自定义接口(interface)。通过使用此接口(interface)中的方法比较成对的任务,该服务将:

  1. 如果传入任务被任何正在运行的任务阻止,则阻止传入任务。
  2. 在完成任务的 Future 时调用挂起任务。
  3. 通过比较确定待处理任务的执行顺序。

阻塞/比较逻辑应该由任务自己提供。这样,线程池类应该只定义池对象接受什么特殊类型的 Comparable,而根本不关心它们真正是什么类型的 Callable是什么,它们的返回类型是什么。


编辑,取三个:基于 Erick Robertsonanswer ,现在可以防止提交臭任务:

public static void test(String[] args) {
A<Valid> scheduler = new A<>();
scheduler.betterSubmit(new Valid()); // applies to method signature
scheduler.betterSubmit(new Forbidden()); // rejected on compile time
scheduler.betterSubmit(new ConformWithValid()); // still appliable because all required interfaces implementations recognised
}

// just a bunch of test classes

private static class Valid implements Comparable<Valid>, Callable<Void> {

@Override
public int compareTo(Valid o) {
return 0;
}

@Override
public Void call() throws Exception {
return null;
}
}

private static class Forbidden implements Comparable<Forbidden>, Callable<Void> {

@Override
public int compareTo(Forbidden o) {
return -1;
}

@Override
public Void call() throws Exception {
return null;
}
}

private static class ConformWithValid implements Comparable<Valid>, Callable<Boolean> {

@Override
public int compareTo(Valid o) {
return 1;
}

@Override
public Boolean call() throws Exception {
return Boolean.FALSE;
}
}

简单又好用!希望有一天这会帮助和我处境相同的人。 :-)

最佳答案

使用 Comparable<T>约束参数而不仅仅是 T .

如果唯一的标准是对象是CallableComparable ,那么您可以将这两个接口(interface)放在参数上。如果需要满足另一个要求,甚至可以保留将命名类添加到参数的选项。您需要抑制一个警告,但这是一种安全的抑制,因为您知道 T延伸Comparable<T> .

public class A<T extends Comparable<T>> {

// this is just an example of usage of T type
List<T> comparables;

ExecutorService someExecutorService = null;

int compareSomething(T smth) {
return this.comparables.get(0).compareTo(smth);
}

<V> Future<V> submit(Callable<V> task) {
return this.someExecutorService.submit(task);
}

@SuppressWarnings("unchecked")
<V, W extends Callable<V> & Comparable<T>> Future<V> betterSubmit(W task) {
if(this.compareSomething((T) task) != 0)
throw new RuntimeException("");
return this.someExecutorService.submit(task);
}
}

我在使用另一个类时遇到了同样的问题,该类将自身引用为其自身的通用参数,如下所示。我认为这还不是一个干净的实现,但我喜欢你的例子。它提供了一个很好的简洁用例,我可以在它之后设计一些新代码。我通常不喜欢抑制警告,但我真的不介意它,因为只有这种方法受到影响。我希望这会有所帮助!

关于java - 将特定于类和特定于方法的泛型封装在一种类型中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26096736/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com