用于处理通用参数的 JDK 接口
JDK 中是否有一个看起来像这样的接口:
public interface Callback<T> {
public void process(T t);
}
要求是实现一个运行代码的回调,但不返回任何内容。
我可以编写自己的轮子(只需使用此处的示例代码),但我想使用现有的轮子(如果存在),而不是重新发明一个轮子。
Is there an interface from the JDK that looks something like this:
public interface Callback<T> {
public void process(T t);
}
The requirement is to implement a callback that runs code, but doesn't return anything.
I could write my own (by simply using the example code here), but I'd like to use an existing wheel if one exists, rather that reinventing one.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
所以你需要类似的东西
JDK 中只有 3 个接口是这样的
显然你不会喜欢它们。
Async IO 有回调接口,但是稍微复杂一些:
So you need something like
Only 3 interfaces in JDK are like that
Obviously you won't like them.
Async IO has a callback interface, but it's a bit more complicated:
不,我不相信目前有这样的界面。目前预计在 JDK 8 中会有一个这样的接口,称为 Block(我认为有一个 apply 方法)...尽管从现在到现在这个名称很可能会发生变化然后。
No, I don't believe there's such an interface currently. There's currently slated to be such an interface, called
Block
(with anapply
method, I think), in JDK 8... though the name could well change between now and then.这看起来像 Guava 的
函数
,但函数允许返回某些内容。因此,它看起来不是 JDK 的一部分,但 Guava 现在非常常用,您可能会发现它很方便。
This looks like Guava's
Function
, except a Function is allowed returning something. It thus looks like aNot part of the JDK, but Guava is so commonly used now that you might find it handy.
根据我的经验,JDK 中没有现成的这样的接口。泛型在 Java 游戏中出现得很晚。在此之前,需要以半类型安全的方式将多个类型参数传递给回调,并且事先不了解这些参数结构(我说“半类型安全”是因为事件侦听器是为了测试事件的类型而发明的)并根据需要进行投射)。如果没有泛型,你就无法构建该机制,而且他们也从未重新构建整个 JDK 以考虑泛型(除了集合 API 和其他一些)。这将是一项艰巨的任务,但收效甚微(毕竟,一切都按预期进行)。
因此,观察者/监听者模式在 JDK 库中普遍存在(请参阅 java.util.EventObject、java.util.EventListerner 及其用法)。 Java 还认为,在实现
EventListener
时,接口定义应该更加详细。为了更清晰的实现,该模式的专门实现应该使回调方法名称表明代码的目的(通常也与事件的名称匹配)。例如,ActionEvent#actionPerformed(ActionEvent e)
。该接口不存在的另一个可能原因是 JDK 本身没有使用它。有时您希望
Callback
其他人希望Callback
甚至Callback
等。在没有任何实际用例(JDK 内部)的情况下提供这些接口实际上并不是一个很好的设计策略。缺乏对此类有用构造的支持是 Guava 和 Apache Commons(以及其他)存在的主要原因。不管怎样,我同意@JB Nizet 的观点,你应该使用 Guava。我们没有具体说明为什么以及如何使用该界面,因此留下了很大的猜测空间,但无论出于何种原因,Guava 可能还有其他可能派上用场的功能。
From my experience, there's no such interface readily available in the JDK. Generics only came in late to the Java game. Before that, there was the need to pass around several typed arguments to a callback in a semi-type safe way and without prior knowledge of those arguments structure (I say "semi-type safe" because event listeners were invented to test the event's type and cast as needed). You could not have built that mechanism without generics and they never did re-architect the whole JDK to have generics in mind (except the collections API and a few others). It would have been a massive undertaking with little gains (after all, everything was working as expected).
Hence, the observer/listener pattern that is pervasive on JDK libraries (see
java.util.EventObject
,java.util.EventListerner
and their usages). Java also believes in being a little more verbose during interface definition, when implementingEventListener
. For clearer implementations, specialized implementations of that pattern should make the callback method name demonstrate the purpose of the code (which usually also matches the event's name). E.g.,ActionEvent#actionPerformed(ActionEvent e)
.Another possible for reason for that interface to be absent is that it is not used in the JDK itself. Sometimes you wish for
Callback<T>
others forCallback<T, V>
or evenCallback<T, R, V>
, etc. Providing those interfaces without any real is use case (inside the JDK) is really not a very design policy. That lack of support for such useful constructs is the main reason why Guava and Apache Commons (among others) exist.Anyway, I agree with @JB Nizet that you should be using Guava. We didn't specify why and how you are using the interface, so that leaves a lot of room to speculation, but whatever reason, Guava will probably have other functionality that might come in handy.
这里真正的问题是为什么?为什么你认为为此定义接口比使用 Java 提供的接口更糟糕?你会得到什么?您将失去选择合适名称的能力。我想就是这样。如果您有理由使用 Java 库提供的现有接口,您已经知道它的名称,因为您知道您计划与库的哪一部分进行交互。
使用一种方法创建接口并不是重新发明轮子。
The real question here is why? Why do you think that defining your interface for this is worse than using one provided by Java? What are you going to gain? You will lose the ability to pick an appropriate name. I think that's about it. If there was a reason for you to use an existing interface provided by Java libraries you would already know its name because you would know which part of the library you are planning to interface with.
Creating an interface with one method is not reinventing the wheel.
在 Java 8 中,
java.util .function.Consumer
class 正是您想要的。它有一个非默认方法,该方法接受泛型类型并且不返回任何内容:
In Java 8, the
java.util.function.Consumer
class does exactly what you want.It has one non-default method, which accepts a generic type and returns nothing:
如果您打算应用观察者设计模式,Java 从 JDK 1.0 开始就在其标准库中支持它。您正在寻找的接口是java.util.Observer。该模式的另一面是 java.util.Observable 类。基本上,你扩展java.util.Observable,然后注册你的观察者(据我所知,观察者可以同时观察多个Observable)。这是相当古老的东西,所以要小心:没有泛型。
If you mean to apply the Observer design pattern, Java supports it in its standard library since JDK 1.0. The interface you are looking for is java.util.Observer. The other side of the pattern is the java.util.Observable class. Basically, you extend java.util.Observable, and then register your Observers (as far as I can understand, an Observer can observe more than one Observable at the same time). It's quite ancient stuff, so beware: no generics.
我使用过 Callable ( http:// /docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Callable.html)在java中实现回调/函子。
您可以使用 java.util.concurrent 中的 Executors 来处理这个问题。
I've used Callable ( http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Callable.html) to implement callbacks/functors in java.
You can process this using the Executors stuff in java.util.concurrent.
这称为注释处理。 JSR 269:可插入注释处理 API 定义了 API,它是JDK 6。您可以从 这里和这里。
It is called annotation processing. JSR 269: Pluggable Annotation Processing API defines the API and it is part of JDK 6. You can start from here and here.