218

I am looking to implement a functionality in a list of object as I would in C# using an extension method.

Something like this:

List<DataObject> list;
// ... List initialization.
list.getData(id);

How do I do that in Java?

Fabio Milheiro
  • 8,100
  • 17
  • 57
  • 96
  • Thanks for the answers! Creating a subclass seems to be the way to go. – Fabio Milheiro Dec 05 '10 at 17:46
  • 8
    Check this one: github.com/nicholas22/jpropel, example:new String[] { "james", "john", "john", "eddie" }.where(startsWith("j")).distinct(); It uses lombok-pg which provides the extension method goodness. – NT_ Oct 07 '11 at 20:30
  • 7
    Microsoft definitely got it right when they allowed extensions. Subclassing to add new functionality doesn't work if I need the function in a class returned to me elsewhere. Like adding methods to String and Date. – tggagne Jan 13 '12 at 20:32
  • 4
    i.e. java.lang.String is a final class,so you can't extend it. Using static methods is a way but it shows code unreadable sometimes.I think C# left an age as a computer lang. Extension methods,partial classes,LINQ and so on.. – Davut Gürbüz Jul 27 '12 at 13:04
  • 2
    I think this article will solve your problem.[Why extension methods are evil ?](http://weblogs.java.net/blog/forax/archive/2009/11/28/why-extension-methods-are-evil) – Roadrunner Mar 30 '13 at 05:53
  • 7
    @Roadrunner, rofl! The best retort to a missing language feature is that said missing language feature is evil and unwanted. This is known. – Kirk Woll Aug 08 '13 at 18:42
  • 7
    Extension methods are not "evil". They greatly improve code readability. Just one more of the many poor design decisions in Java. – csauve Jul 29 '15 at 03:29
  • 2
    Five years ago, the fact that Java had no extensions, made Java look ten years old. Today, the fact that Java had no extensions, made Java look twenty years old. It's just ridiculous. – Fattie Nov 28 '16 at 18:58
  • @csuave You are wrong. If you think that calling a static method is bad, read again Microsoft documentation about extension methods. Quote from documentation: In your code you invoke the extension method with instance method syntax. However, the intermediate language (IL) generated by the compiler translates your code into a call on the static method. Therefore, the principle of encapsulation is not really being violated. In fact, extension methods cannot access private variables in the type they are extending. – Santos Zatarain Vera Jan 27 '17 at 01:05
  • @SantosZatarainVera I don't think csauve is against calling static methods. He just meant that Java could/should have allowed for extension methods because, accoring to him, "they greatly improve code readability" and I agree. – Fabio Milheiro Jan 27 '17 at 10:47
  • 1
    @FabioMilheiro I'm in agree with "they greatly improve code readability". I'm not in agree with words "poor design", i cited Microsoft documentation because of this words. Saying "java is bad designed" is like saying "c# is bas designed" because both use almost the same implementation rules for OOP. – Santos Zatarain Vera Feb 03 '17 at 06:23
  • @SantosZatarainVera Sure, I get it now. I understand. Thanks for the clarification. – Fabio Milheiro Feb 03 '17 at 10:17
  • 1
    The last 10 years i programmed in both languages and java has lost its advantage. Java lambda is the biggest non-intuitive, non consistent framework i have seen. C# kept it simple following the SQL pattern `FROM, GROUP BY, SELECT, PROJECTION`. In java they mixed this order inconsistently. C# getter / setter auto support. Also the interface aproaches like JPA is C# pushing to new level with core. ORM support with lambda since day one is also a C# key. We still have to use error prone strings. C# is also attacking the easy portability of severs now. – djmj Nov 06 '20 at 18:20

14 Answers14

248

Java does not support extension methods.

Instead, you can make a regular static method, or write your own class.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 85
    Im spoiled after using extension methods - but static methods will do the trick as well. – bbqchickenrobot Feb 04 '12 at 02:13
  • 4
    It's worth to point out that C#'s extension methods are the same thing. The C# compiler replaces extension method with a call of a static method as this answer mentions. So in short: it's just a matter of syntax. – MasterMastic Nov 24 '12 at 05:25
  • 39
    But the syntax is so nice, and makes the program easier to understand :) I also like how Ruby allows you to do almost the same thing, except you can actually modify the built in classes and add new methods. – knownasilya Jan 17 '13 at 19:15
  • 2
    It is just a bit more readable to use extension methods. It is mostly syntactical sugar and really the same thing to the compiler, but typing it out and reading it is just better. – Rhyous Sep 27 '13 at 01:04
  • 29
    @Ken: Yes, and that's the whole point! Why do you write in Java and not directly in JVM byte code? Isn't it "just a matter of syntax"? – Fyodor Soikin Nov 01 '13 at 15:34
  • 1
    @FyodorSoikin I think there's a difference between compilation and syntactic sugar. I say that because it's not like we're talking about a missing feature. Nevertheless I think you do raise a valid point. – MasterMastic Nov 01 '13 at 17:29
  • 4
    I'm in the same boat. Started writing Android Application. Where are my lambdas, extentions, linq? Lambda extentions were so much better, not I was to write each algorithm for sort, orderby, etc.. I guess its good practice. – harsimranb Mar 01 '14 at 03:05
  • Java 8 supports extension methods – DarVar Mar 19 '14 at 19:34
  • 4
    @DarVar: Wrong. Default implementations of interface methods are not as flexible as extension methods. – SLaks Mar 19 '14 at 19:37
  • 2
    I really want extension methods for refactoring. They are not just convenient. It lets me take an object that got too big and refactor logic out of it without having to change all the places the object is used. I could just wrap the new extracted code in an extension method extending the old object. That way the existing call don't change and the object got smaller. My job would be significantly more productive with extension methods in Java. – jrizzo Apr 25 '14 at 14:39
  • 1
    @Pathachiever11 - checkout Xamarin for Android! Xamarin FTW! – bbqchickenrobot Sep 28 '14 at 21:15
  • 36
    Extension methods can make code much more elegant compared to extra static methods from some other class. Almost all more modern languages allow for some kind existing class extension: C#, php, objective-c, javascript. Java surely shows its age here. Imagine you want to write a JSONObject to disk. Do you call jsonobj.writeToDisk() or someunrelatedclass.writeToDisk(jsonobj) ? – woens Oct 03 '14 at 21:32
  • 26
    Reasons to hate Java keep growing. And I stopped looking for them a couple of years ago...... – John Demetriou Oct 18 '15 at 17:26
  • Just to add here you can write a static method in any class like "UtilsClass" or whatever and then statically import that method into any other class file you want. So in a sense it gives pretty much the same functionality as C# extension methods. You can use that method anywhere as long as it matches the parameter type and has proper access. – DtechNet Oct 28 '15 at 14:48
  • 1
    It broke my heart! I am now a C# Die Hard Lover! – Dk358 Jan 20 '16 at 03:44
  • 1
    and extension methods on interface is **huge** and makes it even worse for Java. – jungle_mole Feb 29 '16 at 19:05
  • what about interface static methods aka default methods? – M.kazem Akhgary Oct 21 '18 at 05:55
  • @M.kazemAkhgary Only possible at interfaces you own. For readability it is very different to have `ComparableUtils.isGreaterThen(a, b)` then `a.isGreaterThen(b)`. Even i wrote this utility functions i still have to recheck if its `a => b` and not around. With extensions this is much clearer. A big disadvantage of java and in the last 10 years C# has much more improved than java. Java lambdas are a also a non-intuitive joke compared to C#. Sadly our whole stack is in java. Even with static utility functions you can write code in C# with much less and still more readable lines. – djmj Nov 06 '20 at 18:13
  • 1
    Everyone here talks about syntactic sugar etc but seem to forget a very important use case for extension methods. We can operate on a list object for example and add methods that the standard library doesn’t have. We have then successfully extended the standard library instead of writing different classes for every library that one then needs to remember. Combine this with higher kinded types and you got a generic possibility to extend the language. – Daniel Jacob Mar 11 '21 at 08:40
  • 1
    @SLaks or anyone, could you possibly just ADD AN EXAMPLE of such a static? Say I want an extension on **RecyclerView**. Do you mean to say, make a new class, named perhaps **RecyclerViewUtils** and then have static methods (so **RecyclerViewUtils.setColor** and then it would be called **RecyclerViewUtils.setColor( yourRV, green )** (Whereas with an extension yourRV.setColor(green) ) Is that the usual idiom? What is the usual naming idiom? Pls explain for swift/c# programmers :) – Fattie Mar 27 '21 at 15:08
  • 1
    Do you guys have one big "Utils" class which has extension for all classes, or, do you have a different utils class for each class you are writing extensions for? – Fattie Mar 27 '21 at 15:10
  • @Fattie You have an ExtensionMethods class in each project. – Mike Lowery Jan 25 '23 at 19:55
  • does java support extension methods yet? – theonlygusti Jun 18 '23 at 15:23
53

Extension methods are not just static method and not just convenience syntax sugar, in fact they are quite powerful tool. The main thing there is ability to override different methods based on different generic’s parameters instantiation. This is similar to Haskell’s type classes, and in fact, it looks like they are in C# to support C#’s Monads (i.e. LINQ). Even dropping LINQ syntax, I still don’t know any way to implement similar interfaces in Java.

And I don’t think it is possible to implement them in Java, because of Java’s type erasure semantics of generics parameters.

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
user1686250
  • 815
  • 7
  • 10
  • 2
    They also allow you to inherit multiple behaviors (sans polymorphism). You can implement multiple interfaces, and with that comes their extension methods. They also allow you to implement behavior you want to attach to a type without having it globally associated with the type system-wide. – Clever Neologism Apr 13 '16 at 21:39
  • 51
    This whole answer is wrong. Extension methods in C# are just syntactic sugar that the compiler rearranges a little to move the target of the method call to the first argument of the static method. You can not override existing methods. There is no requirement that an extension method be a monad. Its literally just a more convenient way to call a static method, which gives the appearance of adding instance methods to a class. [Please read this if you agree with this answer](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods) – Matt Klein Jun 07 '17 at 15:46
  • 3
    well, in this case, define what syntax sugar is, I would call a syntax sugar to be internal macro syntax, for extension methods compiler must at least look up the static class the extension method is located to substitute. There is nothing in the answer about the method should be monad which is non-sense. Also, you can use it for overloading, but it is not extension methods feature, it is a plain parameter type based overloading, the same way it would work if the method is called directly, and it will not work in many interesting cases in Java because of generics type arguments erasure. – user1686250 Jul 03 '17 at 07:46
  • 2
    @user1686250 It possible to implement in Java (by "Java" I assume you mean bytecode that runs on a JVM)... Kotlin, which compiles to bytecode has extensions. It is just syntactic sugar over static methods. You can use the decompiler in IntelliJ to see what the equivalent Java looks like. – Jeffrey Blattman Dec 05 '18 at 00:22
  • @user1686250 Could you develop what you are writing about generics (or give a link) because I absolutely don't get the point about generics. In which way other than usual static methods is it related to? – C.Champagne Jan 12 '20 at 12:44
  • To extend @MattKlein's comment: This answer is indeed wrong. Extension methods cannot override any method. Whenever there are conflicting methods, the class's own method is **always** prioritised. This is logical, because otherwise you could break an entirely library by just writing a single extension method. Example: https://pastebin.com/vr2HXa56 Here, it's impossible to reach `FooExtensions.Test` unless you use the non-extension syntax: `FooExtensions.Test(foo, "haha")`. – Didii Feb 17 '20 at 10:27
  • 4
    People who say its `just` syntax sugar may never had to manage a lot of code or do reviews. `Readability` is the most important thing in programming today, unless you are doing heavy performance things at assembler or GPU level. I have so many codes to maintain and i have no time to follow all those unreadable static method calls. If you combine those with java lambda your code will look awful. Some lambdas look so bad and complicated you better use old `foreach` instead. In future i will even change stack from java to C# if java does not improve. – djmj Nov 06 '20 at 18:32
  • Another syntax desaster is the `Comparable` interface designed for theory but not practical since it lacks all basic comparison like `eq`, `gt` operators. At beginning you learn nonsene of `a.compareTo(b) < -1` or such instead java just provide a simple additional `a.isLessThen(b)` method. Now we are stuck with `ComparableUtils.isLessThen(a, b)` as a compromise. Java is sadly stuck 10 years behind now. – djmj Nov 06 '20 at 18:37
  • Generics are completely unrelated to extension methods. I.e. the "because of Java's type erasure semantics" bit is wrong. Java simply does not support them. – toolforger Feb 27 '22 at 22:10
36

Project Lombok provides an annotation @ExtensionMethod that can be used to achieve the functionality you are asking for.

Thomas Eizinger
  • 1,404
  • 14
  • 25
18

Technically C# Extension have no equivalent in Java. But if you do want to implement such functions for a cleaner code and maintainability, you have to use Manifold framework.

package extensions.java.lang.String;

import manifold.ext.api.*;

@Extension
public class MyStringExtension {

  public static void print(@This String thiz) {
    System.out.println(thiz);
  }

  @Extension
  public static String lineSeparator() {
    return System.lineSeparator();
  }
}
M.Laida
  • 1,818
  • 1
  • 13
  • 19
14

There is no extension methods in Java, but you can have it by manifold as below,

You define "echo" method for strings by below sample,

@Extension
public class MyStringExtension {
    public static void echo(@This String thiz) {
        System.out.println(thiz);
    }
}

And after that, you can use this method (echo) for strings anywhere like,

"Hello World".echo();   //prints "Hello World"
"Welcome".echo();       //prints "Welcome"
String name = "Jonn";
name.echo();            //prints "John"


You can also, of course, have parameters like,

@Extension
public class MyStringExtension {
    public static void echo(@This String thiz, String suffix) {
        System.out.println(thiz + " " + suffix);
    }
}

And use like this,

"Hello World".echo("programming");   //prints "Hello World programming"
"Welcome".echo("2021");              //prints "Welcome 2021"
String name = "John";
name.echo("Conor");                  //prints "John Conor"

You can take a look at this sample also, Manifold-sample

Furkan Öztürk
  • 1,178
  • 11
  • 24
9

The XTend language — which is a super-set of Java, and compiles to Java source code1 — supports this.

jpaugh
  • 6,634
  • 4
  • 38
  • 90
Sam Keays
  • 736
  • 1
  • 5
  • 17
  • When that code which is not Java is compiled to Java, do you have an extension method? Or the Java code is just a static method? – Fabio Milheiro Apr 16 '14 at 22:06
  • @Bomboca As others have noted, Java doesn't have extension methods. So XTend code, compiled to Java, doesn't somehow create a Java extension method. But if you work in XTend exclusively you won't notice or care. But, to answer your question, you don't necessarily have a static method either. The principal author of XTend has a blog entry about this at http://blog.efftinge.de/2011/11/whats-so-special-about-xtends-extension.html – Erick G. Hagstrom Feb 15 '15 at 21:34
  • Yes, don't know why I didn't think that too. Thanks! – Fabio Milheiro Feb 16 '15 at 22:43
  • @Sam Thanks for introducing me to XTend -- I'd never heard of it. – jpaugh Dec 22 '15 at 18:14
8

Another option is to use ForwardingXXX classes from google-guava library.

iggymoran
  • 4,059
  • 2
  • 21
  • 26
Aravind Yarram
  • 78,777
  • 46
  • 231
  • 327
5

It looks like there is some small chance that Defender Methods (i.e. default methods) might make it into Java 8. However, as far as I understand them, they only allow the author of an interface to retroactively extend it, not arbitrary users.

Defender Methods + Interface Injection would then be able to fully implement C#-style extension methods, but AFAICS, Interface Injection isn't even on the Java 8 road-map yet.

jpaugh
  • 6,634
  • 4
  • 38
  • 90
Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653
3

Java does not have such feature. Instead you can either create regular subclass of your list implementation or create anonymous inner class:

List<String> list = new ArrayList<String>() {
   public String getData() {
       return ""; // add your implementation here. 
   }
};

The problem is to call this method. You can do it "in place":

new ArrayList<String>() {
   public String getData() {
       return ""; // add your implementation here. 
   }
}.getData();
AlexR
  • 114,158
  • 16
  • 130
  • 208
  • 121
    That is _utterly_ useless. – SLaks Dec 05 '10 at 17:11
  • 3
    @Slaks: Why exactly? This is a "write your own class" suggested by yourself. – Goran Jovic Dec 05 '10 at 17:47
  • 27
    @Goran: All this allows you to do is define a method, then call it immediately, _once_. – SLaks Dec 05 '10 at 21:44
  • 4
    @Slaks: All right, point taken. Compared with that limited solution, writing a named class would be better. – Goran Jovic Dec 06 '10 at 17:40
  • There is a big, big difference between C# extension methods and Java anonymous classes. In C# an extension method is syntactic sugar for what is really just a static method. The IDE and compiler make an extension method appear as though it is an instance method of the extended class. (Note: "extended" in this context does not mean "inherited" as it normally would in Java.) – HairOfTheDog Nov 05 '13 at 17:40
  • Ugly, but I can see some uses when playing in the IDE late at night lol – pqsk Mar 06 '15 at 21:57
  • @SLaks not anymore! If list is declared using var you can call it later because lists type will be exactly your anonymous class. P.S. I know that this discussion was long before Java 11 and vars – Semyon Danilov Apr 16 '22 at 11:15
2

Bit late to the party on this question, but in case anyone finds it useful I just created a subclass:

public class ArrayList2<T> extends ArrayList<T> 
{
    private static final long serialVersionUID = 1L;

    public T getLast()
    {
        if (this.isEmpty())
        {
            return null;
        }
        else
        {       
            return this.get(this.size() - 1);
        }
    }
}
magritte
  • 7,396
  • 10
  • 59
  • 79
  • 4
    Extension methods are usually for code that cannot be modified or inherited like final/sealed classes and its main power is the the extension of Interfaces e.g. extending IEnumerable. Of course, they are only syntactic sugar for static methods. The purpose is, that the code is much more readable. Cleaner code means better maintanability/evolvability. – mbx Aug 11 '12 at 13:25
  • 1
    That's not just it @mbx. Extension methods are also useful to extend class functionality of non-sealed classes but which you cannot extend because you don't control whatever is returning instances, e.g. HttpContextBase which is an abstract class. – Fabio Milheiro Aug 20 '12 at 19:51
  • @FabioMilheiro I generously included abstract classes as "interfaces" in that context. Auto generated classes (xsd.exe) are of the same kind: you could but shouldn't extend them by modifying the generated files. You normally would extend them by using "partial" which requires them to reside in the same assembly. If they are not, extension methods are a pretty looking alternative. Ultimately, they are only static methods (there is no difference if you look at the generated IL Code). – mbx Aug 20 '12 at 20:58
  • Yes... HttpContextBase is an abstraction although I understand your generosity. Calling an interface an abstraction might have seemed somewhat more natural. Regardless of that, I didn't mean it had to be an abstraction. I just gave an example of a class for which I wrote many extension methods. – Fabio Milheiro Aug 20 '12 at 22:45
2

One could be use the decorator object-oriented design pattern. An example of this pattern being used in Java's standard library would be the DataOutputStream.

Here's some code for augmenting the functionality of a List:

public class ListDecorator<E> implements List<E>
{
    public final List<E> wrapee;

    public ListDecorator(List<E> wrapee)
    {
        this.wrapee = wrapee;
    }

    // implementation of all the list's methods here...

    public <R> ListDecorator<R> map(Transform<E,R> transformer)
    {
        ArrayList<R> result = new ArrayList<R>(size());
        for (E element : this)
        {
            R transformed = transformer.transform(element);
            result.add(transformed);
        }
        return new ListDecorator<R>(result);
    }
}

P.S. I'm a big fan of Kotlin. It has extension methods and also runs on the JVM.

Eric
  • 16,397
  • 8
  • 68
  • 76
2

We can simulate the implementation of C# extension methods in Java by using the default method implementation available since Java 8. We start by defining an interface that will allow us to access the support object via a base() method, like so:

public interface Extension<T> {

    default T base() {
        return null;
    }
}

We return null since interfaces cannot have state, but this has to be fixed later via a proxy.

The developer of extensions would have to extend this interface by a new interface containing extension methods. Let's say we want to add a forEach consumer on List interface:

public interface ListExtension<T> extends Extension<List<T>> {

    default void foreach(Consumer<T> consumer) {
        for (T item : base()) {
            consumer.accept(item);
        }
    }

}

Because we extend the Extension interface, we can call base() method inside our extension method to access the support object we attach to.

The Extension interface must have a factory method which will create an extension of a given support object:

public interface Extension<T> {

    ...

    static <E extends Extension<T>, T> E create(Class<E> type, T instance) {
        if (type.isInterface()) {
            ExtensionHandler<T> handler = new ExtensionHandler<T>(instance);
            List<Class<?>> interfaces = new ArrayList<Class<?>>();
            interfaces.add(type);
            Class<?> baseType = type.getSuperclass();
            while (baseType != null && baseType.isInterface()) {
                interfaces.add(baseType);
                baseType = baseType.getSuperclass();
            }
            Object proxy = Proxy.newProxyInstance(
                    Extension.class.getClassLoader(),
                    interfaces.toArray(new Class<?>[interfaces.size()]),
                    handler);
            return type.cast(proxy);
        } else {
            return null;
        }
    }
}

We create a proxy that implements the extension interface and all the interface implemented by the type of the support object. The invocation handler given to the proxy would dispatch all the calls to the support object, except for the "base" method, which must return the support object, otherwise its default implementation is returning null:

public class ExtensionHandler<T> implements InvocationHandler {

    private T instance;

    private ExtensionHandler(T instance) {
        this.instance = instance;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        if ("base".equals(method.getName())
                && method.getParameterCount() == 0) {
            return instance;
        } else {
            Class<?> type = method.getDeclaringClass();
            MethodHandles.Lookup lookup = MethodHandles.lookup()
                .in(type);
            Field allowedModesField = lookup.getClass().getDeclaredField("allowedModes");
            makeFieldModifiable(allowedModesField);
            allowedModesField.set(lookup, -1);
            return lookup
                .unreflectSpecial(method, type)
                .bindTo(proxy)
                .invokeWithArguments(args);
        }
    }

    private static void makeFieldModifiable(Field field) throws Exception {
        field.setAccessible(true);
        Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField
                .setInt(field, field.getModifiers() & ~Modifier.FINAL);
    }

}

Then, we can use the Extension.create() method to attach the interface containing the extension method to the support object. The result is an object which can be casted to the extension interface by which we can still access the support object calling the base() method. Having the reference casted to the extension interface, we now can safely call the extension methods that can have access to the support object, so that now we can attach new methods to the existing object, but not to its defining type:

public class Program {

    public static void main(String[] args) {
        List<String> list = Arrays.asList("a", "b", "c");
        ListExtension<String> listExtension = Extension.create(ListExtension.class, list);
        listExtension.foreach(System.out::println);
    }

}

So, this is a way we can simulate the ability to extend objects in Java by adding new contracts to them, which allow us to call additional methods on the given objects.

Below you may find the code of the Extension interface:

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

public interface Extension<T> {

    public class ExtensionHandler<T> implements InvocationHandler {

        private T instance;

        private ExtensionHandler(T instance) {
            this.instance = instance;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            if ("base".equals(method.getName())
                    && method.getParameterCount() == 0) {
                return instance;
            } else {
                Class<?> type = method.getDeclaringClass();
                MethodHandles.Lookup lookup = MethodHandles.lookup()
                    .in(type);
                Field allowedModesField = lookup.getClass().getDeclaredField("allowedModes");
                makeFieldModifiable(allowedModesField);
                allowedModesField.set(lookup, -1);
                return lookup
                    .unreflectSpecial(method, type)
                    .bindTo(proxy)
                    .invokeWithArguments(args);
            }
        }

        private static void makeFieldModifiable(Field field) throws Exception {
            field.setAccessible(true);
            Field modifiersField = Field.class.getDeclaredField("modifiers");
            modifiersField.setAccessible(true);
            modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
        }

    }

    default T base() {
        return null;
    }

    static <E extends Extension<T>, T> E create(Class<E> type, T instance) {
        if (type.isInterface()) {
            ExtensionHandler<T> handler = new ExtensionHandler<T>(instance);
            List<Class<?>> interfaces = new ArrayList<Class<?>>();
            interfaces.add(type);
            Class<?> baseType = type.getSuperclass();
            while (baseType != null && baseType.isInterface()) {
                interfaces.add(baseType);
                baseType = baseType.getSuperclass();
            }
            Object proxy = Proxy.newProxyInstance(
                    Extension.class.getClassLoader(),
                    interfaces.toArray(new Class<?>[interfaces.size()]),
                    handler);
            return type.cast(proxy);
        } else {
            return null;
        }
    }

}
0

You can create a C# like extension/helper method by (RE) implementing the Collections interface and adding- example for Java Collection:

public class RockCollection<T extends Comparable<T>> implements Collection<T> {
private Collection<T> _list = new ArrayList<T>();

//###########Custom extension methods###########

public T doSomething() {
    //do some stuff
    return _list  
}

//proper examples
public T find(Predicate<T> predicate) {
    return _list.stream()
            .filter(predicate)
            .findFirst()
            .get();
}

public List<T> findAll(Predicate<T> predicate) {
    return _list.stream()
            .filter(predicate)
            .collect(Collectors.<T>toList());
}

public String join(String joiner) {
    StringBuilder aggregate = new StringBuilder("");
    _list.forEach( item ->
        aggregate.append(item.toString() + joiner)
    );
    return aggregate.toString().substring(0, aggregate.length() - 1);
}

public List<T> reverse() {
    List<T> listToReverse = (List<T>)_list;
    Collections.reverse(listToReverse);
    return listToReverse;
}

public List<T> sort(Comparator<T> sortComparer) {
    List<T> listToReverse = (List<T>)_list;
    Collections.sort(listToReverse, sortComparer);
    return listToReverse;
}

public int sum() {
    List<T> list = (List<T>)_list;
    int total = 0;
    for (T aList : list) {
        total += Integer.parseInt(aList.toString());
    }
    return total;
}

public List<T> minus(RockCollection<T> listToMinus) {
    List<T> list = (List<T>)_list;
    int total = 0;
    listToMinus.forEach(list::remove);
    return list;
}

public Double average() {
    List<T> list = (List<T>)_list;
    Double total = 0.0;
    for (T aList : list) {
        total += Double.parseDouble(aList.toString());
    }
    return total / list.size();
}

public T first() {
    return _list.stream().findFirst().get();
            //.collect(Collectors.<T>toList());
}
public T last() {
    List<T> list = (List<T>)_list;
    return list.get(_list.size() - 1);
}
//##############################################
//Re-implement existing methods
@Override
public int size() {
    return _list.size();
}

@Override
public boolean isEmpty() {
    return _list == null || _list.size() == 0;
}
GarethReid
  • 406
  • 4
  • 12
-8

Java 8 now supports default methods, which are similar to C#'s extension methods.

jpaugh
  • 6,634
  • 4
  • 38
  • 90
DarVar
  • 16,882
  • 29
  • 97
  • 146
  • 9
    Wrong; the example in this question is still impossible. – SLaks Mar 19 '14 at 19:38
  • @SLaks what is the difference between Java and C# extensions? – Fabio Milheiro Mar 20 '14 at 09:38
  • 3
    Default methods can only be defined within the interface. http://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html – SLaks Mar 20 '14 at 14:10
  • DarVar, This comment thread was the only place where *default methods* were mentioned, which I was desperately trying to remember. Thanks for mentioning them, if not by name! :-) (Thanks @SLaks for the link) – jpaugh Dec 22 '15 at 18:15
  • I would upvote that answer, cause the final result from a static method in interface would provide the same use as C# extension methods, however, you still need to implement the interface in your class unlike C# you pass (this) keyword as a parameter – zaPlayer Jan 10 '17 at 08:35
  • I think this is a feasible method in some cases, though you need to add `implements YourInterface` for every class. – Leon Mar 23 '18 at 08:19
  • If you own the interface, default methods can get you much of the behavior of C# extension methods. While this answer does not address the exact use case of the OP, it is a correct solution for many of the use-cases others will have that come looking at this question. – Gordon Bean Mar 15 '19 at 18:28
  • default methods in Java is vastly different from C# extensions. First, the class must extend an interface. And second you must have access to the interface code to make the default methods work with the class instance. With C#, you don't need to own the class definition nor an interface is needed. You can define the extensions anywhere you want, even if you don't own the source code of the class. – TDao Jun 03 '22 at 20:33