Java中扩展方法的实际用途是什么?

时间:2022-09-23 08:09:19

I understand C# extension methods, in that they allow you to add new methods to an already closed class definition. Java defender/extension methods seem to be something wholly different. For example:

我理解C#扩展方法,因为它们允许您向已经关闭的类定义添加新方法。 Java防御者/扩展方法似乎完全不同。例如:

public interface Interfacable {
    public void regular();
    public default void defender() { System.out.println("I am protected"); };
}

Okay, so I get that you can do 'trait-y' things with Java extension methods, but I don't see why it's called the same thing (an "extension") if it seems to uh, not do the same thing. Can someone help me out with this?

好吧,所以我知道你可以用Java扩展方法做'trait-y'的事情,但我不明白为什么它被称为同一个东西(一个“扩展”),如果它似乎呃,不是做同样的事情。有人可以帮我解决这个问题吗?

1 个解决方案

#1


5  

The reason these were added were part of the adding of closures to Java so that there was a easy upgrade path to things like collection classes. The challenge with the addition of closures is there now are a whole lot of functions you want to add to standard collections. However, if you add those to the existing interfaces you break any implementations of those interfaces. A way around this is to add an additional interface with the new methods. This is possible without the virtual extension methods, however, it has its own drawback. Namely, that the implementation of that new interface needs to be added before it can be used. Since there are probably a lot of implementations out there today it may take a long time to get all those implementations upgraded. However, at the same time the way that the methods you want to add are pretty agnostic to the implementation. They should do basically the same thing, at least in the base case. The way the team that built this decided to handle the case was enable the specification of a default behavior that could be overridden. That way with the addition of the interface the functionality is there and it is up to the library writer decide it they want to write a different implementation. The key is they don't have to, or there is a stop gap functionality until they do.

这些添加的原因是为Java添加闭包的一部分,因此有一个简单的升级路径,如集合类。添加闭包的挑战是,现在要添加到标准集合中的功能很多。但是,如果将这些添加到现有接口,则会破坏这些接口的任何实现。解决此问题的方法是使用新方法添加其他接口。这可以在没有虚拟扩展方法的情况下实现,但是它有其自身的缺点。也就是说,需要在使用之前添加新接口的实现。由于今天可能有很多实现,因此升级所有这些实现可能需要很长时间。但是,与此同时,您要添加的方法与实现非常不相关。它们应该基本上做同样的事情,至少在基本情况下。构建它的团队决定处理该案例的方式是启用可以覆盖的默认行为的规范。这样,通过添加接口,功能就在那里,由库编写者决定是否要编写不同的实现。关键是他们没有,或者有一个止损功能,直到他们这样做。

The long an short of it is they basically act like traits and you are correct they aren't the same thing as extension methods in C#. From what I've read the original implementation of this was more C#. However, the decision to use them that way because of the limitations of the style (i.e. unable to override the functionality) and lack of being able to use reflection do discover them. It seems the name stuck, even though the approach to the implementation changed.

很长一段时间它们基本上就像特征一样,你是正确的它们与C#中的扩展方法不同。从我所读到的,最初的实现是更多的C#。但是,由于样式的限制(即无法覆盖功能)以及缺乏使用反射而决定以这种方式使用它们确实会发现它们。尽管实施方法发生了变化,但似乎名称仍然存在。

See the write-up explaining Virtual Extension Methods for full details.

有关详细信息,请参阅解释虚拟扩展方法的文章。

#1


5  

The reason these were added were part of the adding of closures to Java so that there was a easy upgrade path to things like collection classes. The challenge with the addition of closures is there now are a whole lot of functions you want to add to standard collections. However, if you add those to the existing interfaces you break any implementations of those interfaces. A way around this is to add an additional interface with the new methods. This is possible without the virtual extension methods, however, it has its own drawback. Namely, that the implementation of that new interface needs to be added before it can be used. Since there are probably a lot of implementations out there today it may take a long time to get all those implementations upgraded. However, at the same time the way that the methods you want to add are pretty agnostic to the implementation. They should do basically the same thing, at least in the base case. The way the team that built this decided to handle the case was enable the specification of a default behavior that could be overridden. That way with the addition of the interface the functionality is there and it is up to the library writer decide it they want to write a different implementation. The key is they don't have to, or there is a stop gap functionality until they do.

这些添加的原因是为Java添加闭包的一部分,因此有一个简单的升级路径,如集合类。添加闭包的挑战是,现在要添加到标准集合中的功能很多。但是,如果将这些添加到现有接口,则会破坏这些接口的任何实现。解决此问题的方法是使用新方法添加其他接口。这可以在没有虚拟扩展方法的情况下实现,但是它有其自身的缺点。也就是说,需要在使用之前添加新接口的实现。由于今天可能有很多实现,因此升级所有这些实现可能需要很长时间。但是,与此同时,您要添加的方法与实现非常不相关。它们应该基本上做同样的事情,至少在基本情况下。构建它的团队决定处理该案例的方式是启用可以覆盖的默认行为的规范。这样,通过添加接口,功能就在那里,由库编写者决定是否要编写不同的实现。关键是他们没有,或者有一个止损功能,直到他们这样做。

The long an short of it is they basically act like traits and you are correct they aren't the same thing as extension methods in C#. From what I've read the original implementation of this was more C#. However, the decision to use them that way because of the limitations of the style (i.e. unable to override the functionality) and lack of being able to use reflection do discover them. It seems the name stuck, even though the approach to the implementation changed.

很长一段时间它们基本上就像特征一样,你是正确的它们与C#中的扩展方法不同。从我所读到的,最初的实现是更多的C#。但是,由于样式的限制(即无法覆盖功能)以及缺乏使用反射而决定以这种方式使用它们确实会发现它们。尽管实施方法发生了变化,但似乎名称仍然存在。

See the write-up explaining Virtual Extension Methods for full details.

有关详细信息,请参阅解释虚拟扩展方法的文章。