An extension method is the ability to "add" methods directly to an existing type without creating a new one. derived type, recompile, or otherwise modify an existing type. When calling an extension method, there is no discernible difference compared to calling the method actually defined in the type.
Why extension methods are needed
Consider implementing this function: after taking out a string containing multiple product IDs from Redis (each product ID is separated by an English comma), first compare the product IDs Remove duplicates (and maintain the order of elements), and finally use commas to connect the product IDs.
Assume that extension methods can be implemented in Java, and we add the extension method toList for the array (turn the array into a List) , added the extension method toSet for List (turning List into LinkedHashSet), and added the extension method join for Collection (to connect the string forms of elements in the collection using the given connector), then we will be able to write code like this:
I believe you already have the answer to why extension methods are needed at this point:
You can directly enhance the existing class library instead of using tool classes
Compared Use tool classes and use the methods of the type itself to write code more smoothly and more comfortably
The code is easier to read because it is a chain call instead of using static method nesting dolls
Let’s first ask about the recently popular ChatGPT:
ChatGPT’s view is that in Java, extension methods are provided through tool classes Implemented by static method. So next I will introduce a brand new black technology:
Manifold
Manifold and Lombok work similarly, both are compiled through annotation processors processed when. In order to use Manifold effectively, you need to install the Manifold IDEA plug-in in IDEA
and then add annotationProcessorPaths to the maven-compiler-plugin of the project pom:
If you use Lombok in your project, Lombok needs to be added to annotationProcessorPaths:
In JDK, the split method of String uses a string as a parameter, that is, String[] split(String). Let's now add an extension method String[] split(char) to String: Split by given characters.
Based on Manifold, write extension methods:
You can find static methods that are essentially tool classes, but there are some requirements:
Tool classes need to use Manifold’s @Extension annotation
In static methods, the parameters of the target type need to be annotated with @This
The package name where the tool class is located needs to end with extensions.the fully qualified class name of the target type
——Students who have used C# will probably smile knowingly. This is the extension method of imitated C#.
Regarding point 3, the reason for this requirement is that Manifold hopes to quickly find extension methods in the project, avoid annotation scanning of all classes in the project, and improve processing efficiency.
Having the ability to extend methods, now we can call it like this:
Amazing! And you can find that System.out.println(numStrs.toString()) actually prints the string form of the array object - not the address of the array object. Browse the decompiled App.class and observe that the extension method call has been replaced by a static method call
and the toString method of the array uses Manifold to define the array Extension method ManArrayExt.toString(@This Object array):
[Ljava.lang.String;@511d50c0 What, Goodbye, never see you again~
Because extension method calls are replaced with static method calls at compile time, using Manifold's extension method, there is no problem even if the object of the calling method is null, because the processed code passes null as a parameter to the corresponding static method. For example, to extend Collection:
Then when calling:
java.lang.NullPointerException, Goodbye, never see you again~
We see List written like this: @Self is used to indicate what type the annotated value should be. If it is @Self, that is, @Self(false), which represents the annotated value. The value is of the same type as the value of the @This annotation; @Self(true) indicates the type of the elements in the array.
For object arrays, we can see that the toList method returns the corresponding List (T is the type of array element):
But if it is the original Type array, the return value indicated by IDEA is:
But I am using Java, how can erasure method generics have such a great function as List - So you can only use native types to receive this return value:)
##—— Make a wish and hope that Project Valhalla will be released soon. We often see in various projects that everyone first packages an object into Optional, and then performs filter, map, etc. Through the type mapping of @Self, you can add a very practical method to Object like this: Then any object will have the asOpt() method. Compared with the unnatural need to wrap it before: You can now use Optional naturally: Of course, Object is the parent class of all classes, so You still need to think carefully about whether it is appropriate to do it. Extended static methodsWe all know that Java9 adds factory methods to collections:Are you jealous? Because if you are not using Java 9 and above (Java 8: just show me your ID card), you have to use a library like Guava. However, ImmutableList.of is not as good as List.of in use. It comes naturally. It doesn't matter, Manifold said: "It doesn't matter, I will take action." Extending static methods based on Manifold is to add @Extension to the static method of the extension class: Then you can deceive yourself into using a version after Java8 - you can do whatever you want , I use Java8. BTW, because Object is the parent class of all classes, if you add a static extension method to Object, it means that you can directly access this static method anywhere without the need to import - Congratulations You, unlock the "top function".The above is the detailed content of What is Java's missing feature extension methods. For more information, please follow other related articles on the PHP Chinese website!