简体   繁体   English

Java中是否可以对同一接口进行参数化和未参数化的版本?

[英]Are parametrized and unparametrized versions of the same interface possible in Java?

Question

If one defines a public class Something <T> { ... } , then Java will complain about using a raw type if you do this: Something noparam = new Something(); 如果定义了一个public class Something <T> { ... } ,那么Java将抱怨使用原始类型: Something noparam = new Something();

Is it possible to define an interface or class that can be used with or without a type parameter? 是否可以定义可以使用或不使用类型参数的接口或类?

Context 语境

The frontend of a Java app interfaces asynchronously with our backend using callbacks: Java应用程序的前端使用回调与后端异步接口:

public interface ResultCallback <T> {
    public void onResult(T result);
    public void onError();
}

Here's an example of the backend I'm talking about, with some basic CRUD operations using the callback above: 这是我正在谈论的后端的示例,其中使用上述回调进行了一些基本的CRUD操作:

public interface Backend {

    // create a new Comment for a specified blog Post
    public void createComment(Post post, ResultCallback<Comment> callback);

    // retrieve the Comment with the specified UUID
    public void getComment(UUID id, ResultCallback<Comment> callback);

    // delete the Comment with the specified UUID
    public void deleteComment(UUID id, ResultCallback callback);
}

Notice that the delete operation's callback.onResult(T result) will not have a Comment parameter . 请注意,删除操作的callback.onResult(T result) 将没有Comment参数 It might make sense to parametrize that result with a Comment and just "return" the deleted Comment , even if it's just to satisfy the type parameter constraint of ResultCallback . Comment对结果进行参数化并仅“返回”已删除的Comment可能是有意义的,即使它只是为了满足ResultCallback的类型参数约束。 I don't like this idea because the Comment is gone from the backend and no changes to it will persist. 我不喜欢这个想法,因为Comment从后端消失了,对它的任何更改都不会持久。

Just for a usage example, the idea is that ResultCallbacks are defined in the frontend of the app and passed to the async backend. 仅作为一个使用示例,其想法是在应用程序的前端中定义ResultCallbacks并将其传递给异步后端。 For example, to display a comment: 例如,要显示评论:

public CommentRenderer implements ResultCallback<Comment> {
    @Override
    public void onResult(Comment comment) {
        // display the comment, commenter, date, etc. on screen
    }

    @Override
    public void onError(String message) {
        // display an error message
    }
}

No, the closest thing to that comes to mind would be to use ResultCallback<Void> but that would still require you to give the onResult a null-argument which is kind of ugly. 不,最接近的想法是使用ResultCallback<Void>但这仍然需要您为onResult一个null参数,这有点丑陋。

In this case I would recommend you to either use a separate interface for the delete case or let ResultCallback have more than one method: 在这种情况下,我建议您对delete情况使用单独的接口,或者让ResultCallback具有多个方法:

interface ResultCallback<T> {
    void onResult(T t);
    void onDelete(); // Called after delete.
    void onError(String message);
}

If you think it is frustrating to override the onDelete even though you're rarely interested in "listening" for these type of events, you could give it an empty default implementation: 如果您认为覆盖onDelete令人沮丧,尽管您很少对“监听”这些类型的事件感兴趣,则可以给它一个空的默认实现:

...
    default void onDelete() {
        // do nothing by default
    }
...

An alternative for pre-Java 8, is to use an Adapter which would look like follows: Java 8之前的替代方法是使用如下所示的Adapter

abstract class ResultAdapter<T> implements ResultCallback<T> {
    @Override
    public void onResult(T t) {
    }

    @Override
    public void onDelete() {
    }

    @Override
    public void onError(String msg) {
    }
}

在这种情况下,您始终可以使用ResultCallback<Void>并使用null

How a bout extended Generic Type? 如何扩展通用类型?

public class Foo<T extends Comment> { ... }
public class FooDefault extends Foo< Baz > { ... }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM