0

Is there any way to define methods via method references, as demonstrated by the following imaginary code (and imaginary syntax)?

class A
{
    public Sometype somefunction(Argtype arg)
    { ... return somevalue; ..}
}

class B
{
    public Sometype method = A::somefunction;
}

or

class C
{
    public Sometype method(Argtype arg) = A::somefunction;
}

A similar feature would seem quite useful to me. Methods are known at compile time, so any definition in class B or C might simply (after a type check) take over a reference to an already known method in A. The advantage: faster calls (one less required than even in a direct call from a new method) - where I am not sure whether Java compilers do not optimize anyway?

Is there any way to achieve that already now in Java (if so, it has evaded my search successfully)? Or are there good reasons not to introduce that to Java? Are there any workarounds which provide similar performance advantage?

PS: I get the message that similar question titles have been downvoted and/or closed. If this applies here, too, please help me to understand why. Thanks in advance!

  • What about using decorator. ? you can defined the method in class A and call the same method from class B or C. if you can share you exact use-case. that will clear your requirement. and you may get more accurate answers – Pramod Sep 21 '17 at 07:58
  • Performance advantage? Is this a question about micro-optimization? – Kayaman Sep 21 '17 at 07:59
  • `Sometype` is the return type of `somefunction`. The fields in classes `B` and `C` must be of type `Function` or something similar. – dpr Sep 21 '17 at 08:06
  • @Kayaman, more general: It seems so obvious to me that a similar feature should be a consequence of the existence of method refs. I hope to gain more insight from the answers. – BlondMammuth Sep 21 '17 at 08:08
  • @dpr, if one used lambda expressions aka functional interfacs and anonymous classes - yes. But I was hoping for a simple and consistent way of assigning method references to class methods at definition time, thus avoiding all that overhead. It seems that my hope is not fulfilled, at least in Java 8, and it would be quite interesting whether future versions could provide that or whether there are conceptual reasons against it. – BlondMammuth Sep 21 '17 at 08:56

2 Answers2

2

This question can be split in 2 different ones.

  1. How can I use class A methods from other classes
  2. How can I specify the return type of a method at runtime

Regarding the first one, take a look at Java inheritance, polymorphism, abstract classes and interfaces.

I would have defined class A as abstract:

abstract class A{
  public Sometype somefunction(Argtype arg)
     { ... return somevalue; ..}
}

and B, C extends it:

class B extends A{
}

In this way B and C inherits all the methods implemented in A and you can perform something like this:

B b = new B();
b.somefunction(arg);

Moreover, referring to the second question if you don't know the return type of this method at compile time you can exploit java generics (if polymorphism isn't enough). In this way class A becomes:

abstract class A{
    public T somefunction(Class<T> type)
    { ... return somevalue; ..}
}

and the previous example code becomes:

B b = new B();
b.somefunction(String.class);
desoss
  • 572
  • 4
  • 26
  • This is a specific workaround, and (like the other answer), it tells me that what I had in mind is not part of the Java language specification. So there is no "set this method to that method" option. It is really quite interesting that the simple concept of assigning (matching) method references to method table entries is not there in Java, although it seems that this would be easy from Java 8 on. – BlondMammuth Sep 21 '17 at 08:51
2

You could do something like this:

class A {
    public static Sometype someStaticFunction(Argtype aArg) {
      ...
    }

    public Sometype someNonStaticFunction(Argtype aArg) {
      ...
    }
}

class B {
    private Function<Argtype, Sometype> mStaticFunction = A::someStaticFunction;

    private Function<Argtype, Sometype> mNonStaticFunction = new A()::someNonStaticFunction;

    public Sometype applyStatic(Argtype aArg) {
      return mStaticFunction.apply(aArg);
    }

    public Sometype applyNonStatic(Argtype aArg) {
      return mNonStaticFunction.apply(aArg);
    }
}

However I don't see any point in this, regrading design, performance or any other aspects.

dpr
  • 10,591
  • 3
  • 41
  • 71
  • Indeed there is no point, because calling the other method can easily be achieved just calling it. But I assume the answer to my question is simply "no, you cannot assign method references to class methods at definition". Still, I will keep this neat little trick in mind, who knows where it might come in handy? – BlondMammuth Sep 21 '17 at 08:45