Giving the parameter System.out::println to a method - java

I forgot a concept that I used and can't remember it.
For the context, I used to have a method like toString() which had a parameter. This parameters allowed me to call my method like myMethod(System.out::println) to print it on the screen, but also to print it in a file with the same syntax.
Does anyone know what can be this parameter? the concept?
I think it's kind of a FunctionalInterface but I don't know what it is.

This is called method reference and applies when you know what method you want to call, provided the method already exist.
From the tutorial :
Because this lambda expression invokes an existing method, you can use
a method reference instead of a lambda expression:
Arrays.sort(rosterAsArray, Person::compareByAge);
Available since Java-8.
An exemple using what you want:
public static void function(String s, Consumer<String> f) {
f.accept(s);
}
public static void main(String args[]) {
String test1 = "test";
String test2 = "test2";
function(test1, System.out::println);
function(test2, System.out::println);
function(test1, System.out::print);
function(test2, System.out::print);
}

This goes well with java 8 functional interface:
#FunctionalInterface
static interface MyPrinter {
public void println(String line);
}
static void myMethod(MyPrinter mp) {
mp.println("Hello wolrd");
}
...
public static void main(String[] args) throws IOException {
myMethod(System.out::println);
PrintWriter pw = new PrintWriter("myFile.txt");
myMethod(pw::println);
pw.close(); //never forget to close file output streams!
//EDIT: note that you can of course store your MyPrinter in a variable:
MyPrinter mp = System.err::println;
myMethod(mp);
}

Would this work for you?
public class C {
static void myMethod(java.io.PrintStream p) {
p.println("Hello!");
}
public static void main(String args[]) {
myMethod(System.out);
}
}
Unfortunately you can't pass System.out.println directly, because in Java methods (before Java 8) are not first-class objects. All you can do with a method is calling it. As a workaround, you can introduce an interface and create an adapter class.

Related

Inline Java method defined for a class is not available when calling the object [duplicate]

Is there any Java syntax to access new methods defined within anonymous inner classes from outer class? I know there can be various workarounds, but I wonder if a special syntax exist?
For example
class Outer {
ActionListener listener = new ActionListener() {
#Override
void actionPerformed(ActionEvent e) {
// do something
}
// method is public so can be accessible
public void MyGloriousMethod() {
// viva!
}
};
public void Caller() {
listener.MyGloriousMethod(); // does not work!
}
}
MY OWN SOLUTION
I just moved all methods and members up to outer class.
Once the anonymous class instance has been implicitly cast into the named type it can't be cast back because there is no name for the anonymous type. You can access the additional members of the anonymous inner class through this within the class, in the expression immediate after the expression and the type can be inferred and returned through a method call.
Object obj = new Object() {
void fn() {
System.err.println("fn");
}
#Override public String toString() {
fn();
return "";
}
};
obj.toString();
new Object() {
void fn() {
System.err.println("fn");
}
}.fn();
identity(new Object() {
void fn() {
System.err.println("fn");
}
}).fn();
...
private static <T> T identity(T value) {
return value;
}
A student in my class asked our professor if this could be done the other day. Here is what I wrote as a cool proof of concept that it CAN be done, although not worth it, it is actually possible and here is how:
public static void main(String[] args){
//anonymous inner class with method defined inside which
//does not override anything
Object o = new Object()
{
public int test = 5;
public void sayHello()
{
System.out.println("Hello World");
}
};
//o.sayHello();//Does not work
try
{
Method m = o.getClass().getMethod("sayHello");
Field f = o.getClass().getField("test");
System.out.println(f.getInt(o));
m.invoke(o);
} catch (Exception e)
{
e.printStackTrace();
}
}
By making use of Java's Method class we can invoke a method by passing in the string value and parameters of the method. Same thing can be done with fields.
Just thought it would be cool to share this!
Your caller knows listener as an ActionListener and therefore it doesn't know anything about that new method. I think the only way to do this (other than doing reflection gymnastics, which really would defeat the purpose of using an anonymous class, i.e. shortcut/simplicity) is to simply subclass ActionListener and not use an anonymous class.
Funny enough, this is now allowed with var construct (Java 10 or newer). Example:
var calculator = new Object() {
BigDecimal intermediateSum = BigDecimal.ZERO;
void calculate(Item item) {
intermediateSum = Numbers.add(intermediateSum, item.value);
item.sum= intermediateSum;
}
};
items.forEach(calculator::calculate);
Here with method reference, but works with dot method call as well, of course. It works with fields as well. Enjoy new Java. :-)
I found more tricks with var and anonymous classes here: https://blog.codefx.org/java/tricks-var-anonymous-classes/
No, it's imposible. You would need to cast the ActionListener to its real subclass name, but since it's anonymous, it doesn't have a name.
The right way to do it is using reflection:
import java.lang.reflect.InvocationTargetException;
public class MethodByReflectionTest {
public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
Object obj = new Object(){
public void print(){
System.out.println("Print executed.");
}
};
obj.getClass().getMethod("print", null).invoke(obj, null);
}
}
You can check here: How do I invoke a Java method when given the method name as a string?
Yes you can access the method see the example below if any doubt please comment
package com;
interface A
{
public void display();
}
public class Outer {
public static void main(String []args)
{
A a=new A() {
#Override
public void display() {
System.out.println("Hello");
}
};
a.display();
}
}

How to run a code chunk from LeetCode in the local IDE?

All Leetcode questions don't seem to have main methods, I wonder how I could run the code in a local IDE(say, eclipse)? For instance, I was trying to run this one:
Q: Write a method/function to replace all the space in String s to "%20".
The code:
public class ReplaceSpace {
public String replaceSpace(String s) {
StringBuilder res = new StringBuilder();
for(Character c : s.toCharArray()) {
if(c == ' ')
res.append("%20");
else
res.append(c);
}
return res.toString();
}// that'll work in the Leetcode editor
public static void main(String[] args) {
String s = "We are happy.";
System.out.print(s.replaceSpace); //reports "cannot be resolved to a type" error
}
}
Also, if anyone could explain a little why Leetcode editor could run code without the main method it would be great.
To test the code in your local IDE, simply provide your own main. The pre-written code usually contains non-static methods. This gives you two ways to test your code.
Add static
public class ReplaceSpace
{
public static String replaceSpace(String s)
{
...
}
public static void main(String[] args)
{
System.out.println (replaceSpace("We are happy"));
}
}
Create object
public class ReplaceSpace
{
public String replaceSpace(String s)
{
...
}
public static void main(String[] args)
{
ReplaceSpace rs = new ReplaceSpace();
System.out.println (rs.replaceSpace("We are happy"));
}
}
replaceSpace is a method of ReplaceSpace class and not String class. String is the return type for replaceSpace method. You're trying to call the replaceSpace method on the String class object.
In order to run the code, you need to instantiate an object of ReplaceSpace class and then call the replaceSpace method on its object by passing the string which you want to replace as a parameter. Like so:
public static void main(String[] args) {
ReplaceSpace rs = new ReplaceSpace();
String replacedString = rs.replaceSpace("We are happy.");
System.out.println(replacedString);
}
Another way is to make the replaceSpace method static and call the method without an object instantiation.
As to how Leetcode runs the code behind the scenes, they don't need to use main methods to run your code. They just have unit tests written for your function with exhaustive test cases to test your solution rather than running your code via main methods.

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();
}
}

Adding a method to a class using anonymous class [duplicate]

Is there any Java syntax to access new methods defined within anonymous inner classes from outer class? I know there can be various workarounds, but I wonder if a special syntax exist?
For example
class Outer {
ActionListener listener = new ActionListener() {
#Override
void actionPerformed(ActionEvent e) {
// do something
}
// method is public so can be accessible
public void MyGloriousMethod() {
// viva!
}
};
public void Caller() {
listener.MyGloriousMethod(); // does not work!
}
}
MY OWN SOLUTION
I just moved all methods and members up to outer class.
Once the anonymous class instance has been implicitly cast into the named type it can't be cast back because there is no name for the anonymous type. You can access the additional members of the anonymous inner class through this within the class, in the expression immediate after the expression and the type can be inferred and returned through a method call.
Object obj = new Object() {
void fn() {
System.err.println("fn");
}
#Override public String toString() {
fn();
return "";
}
};
obj.toString();
new Object() {
void fn() {
System.err.println("fn");
}
}.fn();
identity(new Object() {
void fn() {
System.err.println("fn");
}
}).fn();
...
private static <T> T identity(T value) {
return value;
}
A student in my class asked our professor if this could be done the other day. Here is what I wrote as a cool proof of concept that it CAN be done, although not worth it, it is actually possible and here is how:
public static void main(String[] args){
//anonymous inner class with method defined inside which
//does not override anything
Object o = new Object()
{
public int test = 5;
public void sayHello()
{
System.out.println("Hello World");
}
};
//o.sayHello();//Does not work
try
{
Method m = o.getClass().getMethod("sayHello");
Field f = o.getClass().getField("test");
System.out.println(f.getInt(o));
m.invoke(o);
} catch (Exception e)
{
e.printStackTrace();
}
}
By making use of Java's Method class we can invoke a method by passing in the string value and parameters of the method. Same thing can be done with fields.
Just thought it would be cool to share this!
Your caller knows listener as an ActionListener and therefore it doesn't know anything about that new method. I think the only way to do this (other than doing reflection gymnastics, which really would defeat the purpose of using an anonymous class, i.e. shortcut/simplicity) is to simply subclass ActionListener and not use an anonymous class.
Funny enough, this is now allowed with var construct (Java 10 or newer). Example:
var calculator = new Object() {
BigDecimal intermediateSum = BigDecimal.ZERO;
void calculate(Item item) {
intermediateSum = Numbers.add(intermediateSum, item.value);
item.sum= intermediateSum;
}
};
items.forEach(calculator::calculate);
Here with method reference, but works with dot method call as well, of course. It works with fields as well. Enjoy new Java. :-)
I found more tricks with var and anonymous classes here: https://blog.codefx.org/java/tricks-var-anonymous-classes/
No, it's imposible. You would need to cast the ActionListener to its real subclass name, but since it's anonymous, it doesn't have a name.
The right way to do it is using reflection:
import java.lang.reflect.InvocationTargetException;
public class MethodByReflectionTest {
public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
Object obj = new Object(){
public void print(){
System.out.println("Print executed.");
}
};
obj.getClass().getMethod("print", null).invoke(obj, null);
}
}
You can check here: How do I invoke a Java method when given the method name as a string?
Yes you can access the method see the example below if any doubt please comment
package com;
interface A
{
public void display();
}
public class Outer {
public static void main(String []args)
{
A a=new A() {
#Override
public void display() {
System.out.println("Hello");
}
};
a.display();
}
}

Equivalent to late static binding(PHP) in other popular languages

<?php
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
static::who(); // Here comes Late Static Bindings
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test(); // Outputs "B"
?>
I want to get an equivalent in Java...so something like
class A {
public static void who(){
System.out.println("A");
};
public static void test(){
who(); //<<< How to implement a static:: thing here???
}
}
class B extends A {
public static void who(){
System.out.println("B");
};
public static void main(String[] args){
B.test(); // Outputs "A" but I want "B"
}
}
I want the who() call inside A::test to resolve as in PHP 5.3 by calling B::who.
EDIT: I know there is no "standard way" of doing this in most popular languages. I'm looking for hacks and such. Also, is this possible in C/C++, or any other popular OOP language?
This is not for any real design on anything. I'm just being curious.
Not possible in Java. (At least not without ugly reflection hacks.)
I encourage you to rethink your design and rely on proper objects.
Related question:
Can I override and overload static methods in Java?
Edit: B.test() will (or can at least according to spec) be compiled into a call to A.test(), so there's no way to discover how the call was made from within A.test(). In other words, there's no way to let the behaviour of A.test depend on if it was called through A.test() or B.test().
Since you're asking out of curiosity, here's AFAIK the closest "solution".
Overload test with a test(Class<?> c) which takes as argument the class which defines the intended who method.
Hide (note that you can't override) test() in class B.
And change the implementation of A.test slightly.
In code:
class A {
public static void who() {
System.out.println("A");
}
public static void test() {
test(A.class);
}
public static void test(Class<?> c) {
//who(); //<<< How to implement a static:: thing here???
try {
c.getMethod("who").invoke(null); // Call static who on given class.
} catch (Exception e) {
}
}
}
public class B extends A {
public static void who(){
System.out.println("B");
}
public static void test() {
test(B.class);
}
public static void main(String[] args){
A.test(); // Outputs "A"
B.test(); // Outputs "B"
}
}
It seems that the compiler generates a call to B.test in the bytecode even though B doesn't declare a method named test.
Bytecode of main method:
invokestatic #5 = Method B.test(()V)
return
Given the names of a class and method ("B" and "who") you can easily use reflection to call the method. So the question becomes
Can you extract B by combining the call stack and bytecode inside A.test?
You'll need to use the return address stored on the stack to locate the call to B.test in the bytecode and extract the declared call. There are plenty of bytecode manipulation libraries, but I don't know if any of them allow you to tie that to the execution stack in the JVM.
You can't override static methods in java.
http://geekexplains.blogspot.co.uk/2008/06/can-you-override-static-methods-in-java.html
Here's an example from Java. It uses Java 8 default methods and getClass(). I bet it works with classes too:
interface A {
default String name() {
return getClass().getName();
}
}
class B implements A {}
public class LateBinding {
public static void main(String[] args) {
// Create an anonymous class in `LateBinding` (called `$1`)
System.out.println(new A(){}.name());
// Instantiate a new `B`
B b = new B();
System.out.println(b.name());
}
}
Results:
$ javac LateBinding.java && java LateBinding
LateBinding$1
B
As you can see the method knows in both cases where it's running, although it's defined in A. This example is not really static, because you can't call getClass() statically, but LSB in PHP is not really limited to static contexts.
There is no elegant way to do it with static method declaration (Only Delphi from what I'm aware of supports override for static methods). However if static is not necessary for you you can write something like this:
class A {
public void who(){
System.out.println("A");
};
public void test(){
who(); //<<< How to implement a static:: thing here???
}
}
class B extends A {
#Override
public void who(){
System.out.println("B");
};
public void main(String[] args){
A instance = new A();
instance.test(); // prints 'A'
instance = new B();
instance.test(); // prints 'B'
}
}
EDIT after clarification:
Pretty hacky way of doing this: Thread.currentThread().getStackTrace() then from top-most record get method and class this method belongs to. Having Class c - you could write c.getMethod("who").invoke(null); to call the correspond who() method.

Categories