Invoking a method of an anonymous class without reflection in java - java

I want to do something like this
static <T> T mine()
{
return new Object(){void hello(){}};
}
so that I can do this
mine().hello();
the intend is to do something like this
mine.hello().hi().bye();
so either I declare classes each with 1 method hello,hi,bye and than return there instances or somehow I could return an anonymous class(with newly defined method) form each method like above. so that I dont have to write lot of classes.
Like it I can do
static <T> T tunnel(T t)
{
return t;
}
tunnel(new Object()
{
void hello()
{
System.out.println("hello");
}
}).hello();
but its of no use, I want to return anonymous object(created in tunnel itself) from tunnel , instead of returning passed argument

You probably want a fluent class. Something like
public class MyFluentClass {
public MyFluentClass methodOne() {
// do something
return this;
}
public MyFluentClass methodTwo() {
// do something
return this;
}
}
And then in your main method:
MyFluentClass myFuent = new MyFluentClass();
myFluent.methodOne().methodTwo();

Related

I need to be able to execute a function call by passing the full function call statement as a parameter - java

lets say I have below
class abc{
void doSomething(String abc){
//does Something
}
}
I need to be able to create a function that I can pass the full call
as parameter.
functionCall(doSomething(abc)){}
please advice if this is possible. similar to what happens in an if
statement.
Create a function that takes a Consumer functional interface as argument
public static void functionCall(Consumer<String> consumer, String value) {
consumer.accept(value);
}
Then use it like below, this solution is for Java 8. For newer versions you can do this in a cleaner way. See answer from #akuzminykh
Abc abc = new Abc();
functionalCall(s -> abc.doSomething(s), "Hi");
You can pass a function with one parameter and no return type as Consumer<T>.
static void functionCall(Consumer<String> function, String argument) {
function.accept(argument); // Call the method with the argument.
}
...
Abc object = new Abc();
Consumer<String> function = object::doSomething; // Get function variable.
functionCall(function, "foobar");
As your method is an instance method, you need to get the method reference through an instance of the class. This is what I have object for. This syntax works on Java 11.0.6.
You can put the method doSomething in an abstract class (Abc) and then create a anonymous class an call the method that you want ie:
public class TemplateExample {
public static void main(String args[]) {
TemplateExample instance = new TemplateExample();
PrintSomething pa = instance.new PrintSomething() {
#Override
void print() {
System.out.println("PrintSomething pa");
}
};
PrintSomething pb = instance.new PrintSomething() {
#Override
void print() {
System.out.println("PrintSomething pb");
}
};
pa.print();
pb.print();
}
abstract class PrintSomething {
abstract void print();
}
}

Convenient way to create a wrapper

Problem
I need to perform logic over and over on the results of several methods. The methods can have arbitrary result types. The simple use case looks like this:
A wrapper class with an execute method:
/**
* Wrapper class which executes inner logic, processes the result of that logic and returns the processed result.
*
* #param <T>
*/
public abstract class Wrapper<T> {
/**
* Perform inner logic
*/
public abstract T run();
/**
* Invoke inner logic and process it.
*/
public T execute() {
T result = run();
// TODO: process result
return result;
}
}
And the logic in an inner class, example usage of the Wrapper:
public class WrapperDemo {
/**
* Simple invocation of the inner logic and then the outer logic
*/
public static Boolean testMethod() {
// wrap around logic and execute
return new Wrapper<Boolean>() {
#Override
public Boolean run() {
// TODO: perform logic, simply returning true for now
return Boolean.TRUE;
}
}.execute();
}
public static void main(String[] args) {
// demo method invocation
Boolean result = WrapperDemo.testMethod();
// process result
System.out.println(result);
System.exit(0);
}
}
I'll have to apply this to several 100s of methods.
Question
Does anyone know a more convenient way to code this with less code for testMethod (e. g. maybe annotation)?
If you have Java 8, you could write the following:
public static <T> T execute(Wrapper<T> wrapper) {
return wrapper.execute();
}
And then use it as following:
public static Boolean testMethod() {
return execute(()-> {
return Boolean.TRUE;
});
}
Though I fail to see how this is better than the following:
public static <T> T wrap(T result) {
// Process result
return result
}
And using it like this:
public static Boolean testMethod() {
return wrap(Boolean.TRUE);
}
If you want to use annotations, you should use a tool that allows such reflection to be used. Basic reflection can't be used because then you can't "intercept" the call. Java's Proxy might help, but you're constrained to use interfaces, which is not always what people want.
cglib is a library that removes all that hassle. With that, you can try the following:
#Target(METHOD)
#Retention(RUNTIME)
public #interface Wrap {
}
class Demo {
#Wrap
public Boolean testMethod() {
return Boolean.TRUE;
}
}
class Wrapper {
public <T> T newInstance(Class<T> type) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(type);
enhancer.setCallback(new InvocationHandler(){
#Override public Object invoke(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
Object result = proxy.invokeSuper(obj, args);
if (method.isAnnotationPresent(Wrap.class)) {
execute(result);
}
return result;
}
});
return enhancer.create();
}
public void execute(Object result) {
// Add custom behavior to #Wrap-ped methods.
}
}
Then you have to call the wrapper like this:
Demo demo = new Wrapper().newInstance(Demo.class);
demo.testMethod();
Other libraries exist too, like Byte Buddy or Javassist. But be careful because Java 9 is very close and forced those libraries into changing their core business very, very quick, possibly making them unstable.
In Java 8, by combination of lambda and default method, you can achieve similar thing without much change in your API (except you need to make Wrapper an interface instead of abstract class)
public interface Wrapper<T> {
public T run();
default public T execute() {
T result = run();
// TODO: process result
return result;
}
}
Then you can call it by
public static Boolean testMethod() {
Wrapper<Boolean> w = ()-> {return Boolean.TRUE;};
return w.execute();
}
But personally I don't think it make much sense.
If you want to add extra logic around a logic, probably what you need is a little twist:
public class ExtraAction<T> {
Supplier<T> supplier;
public ExtraAction(Supplier<T> supplier) {
this.supplier = supplier;
}
public T execute() {
T result = this.supplier.get();
// some extra processsing
return result;
}
}
so it will be called like
Boolean result = new ExtraAction<>(()->{return Boolean.TRUE}).execute();
Even better, make your logic in Wrapper a Function<X,Y>, and make up something to chain your Supplier and Function together, so it will look like
result = Foo.forInput( ()-> { return logicToGetResult(); })
.doExtra(ExtraAction::whateverAction).result();

A java method with both variable return type and variable input arguments

I have an abstract java class "BaseOperation". This class only has a single abstract method:
public abstract T execute()
{
...
return T;
}
Subclasses of BaseOperation must implement this method:
public class GetUsersOperation extends BaseOperation<GetUsersResponse>
{
...
#Override
public GetUsersResponse execute()
{
...
return GetUsersResponse;
}
}
This is a great way to put all common "operation" logic in the BaseOperation class, but still have every concrete subclass's execute() method have a different return type.
Now I need to change this structure to allow the execute() methods to have a variable amount of arguments. For example, one concrete subclass would require:
execute(String, int)
and another would need:
execute(Date, Date, String)
This is tricky, because the execute method is declared in the base class. Simply overloading the execute methods in the base is not ideal. Firstly, the amount of overloads would be huge. Secondly, every subclass will only ever use one of the execute methods, what's the point of all the others?
The (in my opinion) easiest solution would be to declare the execute method with varargs:
execute(Object... arguments)
And then downcast all arguments in the subclasses:
execute(Object... arguments)
{
String s = (String) arguments[0];
...
}
Obviously this has 2 major downsides:
Reduced performance because of all the downcasting operations
Calling the execute() methods is no longer strictly typed because any amount of objects can be passed witout compiler warnings.
Are there patterns or other solutions that could don't have these disadvantages?
You could use a bean holding the parameters:
public interface BaseOperation<T, U> {
T execute(U input);
}
public class GetUsersOperation implements BaseOperation<GetUsersResponse, UserInput> {
#Override
public GetUsersResponse execute(UserInput input) {
Date date = input.getDate();
return new GetUsersResponse(date);
}
}
Your abstract class only has one single abstract method: better use an interface. You can implement several interfaces while you can extend only one class.
As already said, the common approach for solving your issue is using a bean holding parameters. But here is another solution, based on a builder approach:
public interface BaseOperation<T> {
public T execute();
}
public class AddOperation implements BaseOperation<Integer> {
private int a, b;
public void setA(int arg){
a = arg ;
return this;
}
public void setB(int arg){
b = arg;
return this;
}
#Override
public Integer execute() {
return a+b ;
}
}
And then use it like this :
new AddOperation().setA(1).setB(2).execute();
You can mix required and optional parameters in this way:
public class MultipleAddOperation implements BaseOperation<Integer> {
private int sum ;
public MultipleAddOperation(int requiredInt){
sum = requiredInt;
}
public void add(int optionalInt){
sum += optionalInt ;
return this;
}
#Override
public Integer execute(){
return sum;
}
}
And so:
new MultipleAddOperation(5).add(1).add(2).execute();

A sorta extentsion on a method java

So i'm creating a API to java and i need a extention like thing on my method. Example:
someMethod().getName();
Something like that. Anyone know how?
What you are trying to do is something called method chaining. Let's put this example:
obj.methodOne().methodTwo()
This will call methodTwo() from the object returned by the call obj.methodOne(), so you can think the above chain as if it were this:
(obj.methodOne()).methodTwo()
Let's say you have this class:
public class MyClass2 {
public int methodTwo() {...}
}
Then, to be able to call methodTwo from the result of obj.methodOne(), the method methodOne() should return an instance of the class MyClass2:
public class MyClass1 {
public MyClass2 methodOne() {
return new MyClass2(); // returns instance of 'MyClass2'
}
}
Not sure what you mean, but this may help
class Foo {
Object someMethod() {
...
return new Object() {
public String toString() {
return "Bar";
}
}
}
}
What you're doing is returning an anonymous class and that overrides toString().
You can read more about anonymous classes here: http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
I think you are unable to express your question.
1) If you want to have toString() method in a class you can do the following:
public class XYZ
{
//Your properties and methods
#Override
public String toString()
{
//Manipulate what you want to return as a String
return a_string;
}
}
2) You want to call a method on the result of a method. Method Chaining
class XYZ
{
//Your properties and methods
public ABC getABC()
{
return an_ABC_object;
}
}
class ABC
{
public void doSomething()
{
// do some work or print something
}
}
public class Test
{
public static void main(String arg[])
{
XYZ xyz=new XYZ();
xyz.getABC().doSomething();
}
}

Is there any way to have readonly feature without using get() in get() set() model?

Having the get set model:
public class exampleclass
{
private Something something;
public Something getSomething()
{
return something;
}
public void setSomething(Something st)
{
something = st;
}
}
I wanna make something like this:
public class exampleclass
{
public Something something;
public void setSomething(Something st)
{
something = st;
}
}
But i want to have "something" var with readOnly feature out of the class (but rewritable in the own class). Any idea of how to do this for an optimized access. (Think this is gonna be used in android , but using a pure java only framework (libgdx) )
You can set thoose things in constructor and expose public final field:
public class ExampleClass
{
public final Something something;
public ExampleClass(Something st)
{
something = st;
}
}
You could use the final keyword.
The you can assign it once.
e.g
public class Exampleclass
{
public final Something something;
void Exampleclass(Something init) {
this.something = init;
}
}
However the content of Something still could be changed, so you may consider returning a clone() of something. (see the class java.util.Date, you still could set the timestamp, in such cases only clone() or a copy constructor helps) . But if your code is not a public lib, then you can leav that getter with clone() away
public class Exampleclass
{
private Something something;
void Exampleclass(Something init) {
this.something = init;
}
void Something getSomething() {
return something.clone();
}
}
But that depends on Something.
Another soultion is a Factory Pattern, such that only the Factory can create Something.
Then there is no public constructor in Something. Only the factory can create it.
public class Something() {
private int value;
protectectd Something(int value) {
this.value = value;
}
public tostring() {
System.out.println("values = " + value);
}
}
public class SomethingFactory() {
protected static Someting createSomething(int value) {
return new Something(value);
}
}
USage:
Something some = SomethingFactory.createSomething(3);
But read more by search "java Deisgn Patterns Factory" or FactoryPattern
I guess your issue is escaping reference, if you want to save your object while returning, send a copy of reference, you can send cloned object using clone method.
public Something getSomething()
{
return something.clone();
}
This will return object shallow copy, if you want make deep cloning override the clone() method Hope this will help..

Categories