I have following class:
class GroovyTest {
static class MyClass {
}
static main(def s) {
MyClass.print("hello")
}
}
It prints:
hello
Why would I need a print method that prints strings in every class?
Furthermore if I do:
MyClass.methods.each {println it}
It gives me a list of methods that MyClass has and print is not in the list.
Groovy adds many methods to classes at runtime. One of those methods is the print method which is added to java.lang.Object. See https://github.com/groovy/groovy-core/blob/194b29270d418b1b8642f5746a49873018f115c1/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java#L531. The way DefaultGroovyMethods works is such that the first argument to the method definition in that class represents the type that the method will be added to so something like this...
public static someMethod(SomeType o, SomeOtherType arg) {
// ...
}
That means that a method named someMethod will be added to SomeType and that method accepts an argument of type SomeOtherType.
I hope that helps.
Groovy adds a bunch of useful methods to the class Object, which means they are available to any object. Even classes, which are objects themselves. That is why you can do [].println().
This is strategy is used because Groovy, nor Java, have the concept of builtin functions like Python or PHP, which have print and echo, respectively. There are only objects and methods. There is no builtin println which you can simply call from nowhere. This is one of the ways to add a global-ish println function.
Seems like it is a builtin function in Ruby, also, as puts.
Related
This is my first code:
public class MethodReference {
public static void main (String []args) {
Stream<String> s = Stream.of("brown bear", "grizzly");
s.sorted(Comparator.reverseOrder()).forEach(System.out::print);
//...
}
}
Result: grizzlybrown bear
This is my second code:
public class MethodReference {
public static void main (String []args) {
Stream<String> s = Stream.of("brown bear", "grizzly");
s.sorted(Comparator::reverseOrder()).forEach(System.out::print);
//...
}
}
Result: compiler error
My questions:
Why is there a compiler error in the second code?
Can't I use the method reference for static method of functional interface?
I know I can't use method reference with default method of functional interface.
I know I can use method reference with a class in 5 cases:
Class
Class::staticMethod
Class::instanceMethod
instance::instanceMethod
Class::new
Functional Interface
Interface::abstractMethod
Thanks a lot!
Comparator.reverseOrder() is an expression which resolves to the Comparator type, because that's what it returns.
Comparator::reverseOrder is an expression which resolves to a method which takes no arguments and returns a Comparator e.g. a Supplier<Comparator<String>>, though it could be any matching functional interface.
In the second instance you are trying to pass a method (which provides a Comparator) as an argument. The method doesn't want that - it just wants the Comparator itself.
You could think of it like this (just pseudo-code to demonstrate the point):
s.sorted(new Comparator())
vs
s.sorted(new Supplier(new Comparator()))
To answer your second question as to whether it's ever possible to use a method reference for a static method of an interface - yes, absolutely!
If we declare the following method:
<T> void giveMeAComparatorSupplier(Supplier<Comparator<T>> supplier) { }
then we can definitely call it with a method reference
giveMeAComparatorSupplier(Comparator::reverseOrder);
(And FYI your method reference syntax is wrong - it never uses ())
Two things are wrong with your second code. First, method references do not use parentheses or arguments at all. You would need to supply only the method that would be called later; you are not calling the method at that point.
Second, the sorted method takes a Comparator, not a functional interface that would supply a Comparator. The method needs a Comparator already created and ready to go, not a functional interface that will supply a Comparator when needed.
It has nothing to do with the fact that Comparator is an interface; one can generally create a method reference to a static interface method. It has everything to do with the fact that sorted needs an actual Comparator instance and not an instance of a functional interface, which is when you could supply a method reference.
So even if you take off the parentheses, it still won't compile. Only your first code, which directly passes a Comparator, will compile and work as expected.
I was reading up on Polymorphism and after some searching I was confused about about the difference of compile-time and run-time polymorphism.
Lets say i have a class ABC and one other class that extends ABC,
class DEF like so:
class ABC{
public void myMethod(){
System.out.println("Overridden Method");
}
}
public class DEF extends ABC{
public void myMethod(){
System.out.println("Overriding Method");
}
}
public static void main(String args[]){
ABC obj = new DEF();
obj.myMethod();
}
}
If we want to be able to replace a class with another class, which performs the same task but in a different way without having too recompile the class that calls them, Is method overriding the way or method overloading?
I guess you are asking two things
1) I was reading up on Polymorphism and after some searching I was
confused about about the difference of compile-time and run-time
polymorphism.
Let's separate the waters here a little bit...
At compile time the compilator validates and transform the code into bytecodes. The static methods calls are resolved during this phase so you know every time the static method is invoked the same and sole implementation will take place.
run-time polymorphism is what happen at execution to decide what actual implementation of a given method to chosse. Considering that each class in the hierchary provides one implementation of this "polymorphic" method. Behind the curtains the compiler do a lot of work to archieve this, using something known as late binding mechanism.
2) If we want to be able to replace a class with another class, which
performs the same task but in a different way without having to
recompile the class that calls them, Is method overriding the way or
method overloading?
You don't actually say that replaces, inteads talks about extends, that is the thing that your are doing when a class extends another. And the implementations of the a method in parent class can be overwritten in a subclass.
Overload, has nothing to do with hierarchies, is to write the same method with diferents set of parameters.
Overloading is when you create multiple classes with the same method name, but different params. If a subclass has the exact same method name and params, it really ends up being overwriting, whether your put #overwrite on top or not. It´s literally the same exact thing and either way you change the outcome of the method, even if you use the base/super - class as a type.
This could be helpful When do you use Java's #Override annotation and why?
You´ll make your compiler complain that you are not actually overwriting a function if you mistype one of the two and nothing ends up being overwritten and you´ll make your code easier to read. It won´t affect the outcome, but you still should use it for those reasons.
I created a class (class Special) whose method (Special.method()) will react differently depending on the method that calls Special.method(). so, lets say method X in some class calls Special.method(), if certain annotation is present in method X, the calc process invoked inside Special.method() will be different when such annotations didnt exist in the calling method. Also, since I'll be using third party library, it's not guaranteed that same thread will be used when calling Special.method() and method X.
I want to know ways to get reference to an instance method in Java 7
public class MyClass{
public void myMethod(){
....
}
}
I know I can do this
MyClass.class.getMethod(methodName);
but this technique is prone to error since it relies on String input (i.e. when method name is changed, etc). Is there a more reliable way to refer to a method?
Thanks
Java doesn't support method references without some fairly gnarly reflection. Java has functional interfaces that can work like references, but due to their targeted usage, they all take or return at least one value. There's no interface for methods which take no arguments and return void like you have in your example.
// Assignment context
Predicate<String> p = String::isEmpty;
Will declare a method reference to the String#isEmpty() method, which returns a boolean. That and similar interfaces exist in the java.lang.function package.
https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
Regarding your edit: If you want to find the caller of your method, see here:
How do I find the caller of a method using stacktrace or reflection?
The currently-accepted answer is incorrect: There is a functional interface compatible with your myMethod (e.g., accepting no parameters, with a void return type), it's just not in java.util.function, it's in java.lang: Runnable:
public class MyClass{
public void myMethod(){
System.out.println("myMethod was called");
}
}
class Example
{
public static void main (String[] args)
{
MyClass c = new MyClass();
Runnable r = c::myMethod; // <===
r.run(); // <===
}
}
Live on IDEOne
They just didn't duplicate it in java.util.function.
There is this function
Transformers.aliasToBean(RoomInfoDTO.class);
Now I would to use the above function in my generic method. How do I pass the class into the method and use it ?
I tried the following but it doesn't work
passThis(PurchaseHistoryDTO.class);
....
function passThis(Class<?> passedClass){
Transformers.aliasToBean(passedClass.getClass());
}
Somehow the function takes the class as class java.lang.Class.
Just pass the argument directly without calling getClass on it. passedClass is a Class object, so calling getClass on it will obviously return java.lang.Class. Just do:
function passThis(Class<?> passedClass){
Transformers.aliasToBean(passedClass); //just pass the class, not the class's class
}
Also, I'm assuming that "function" is shorthand/psuedocode; that won't compile in java. substitute it with a return type, probably void.
As you already passed class object PurchaseHistoryDTO.class in
Class<?> passedClass argument,
just pass "passedClass in the method like :
Transformers.aliasToBean(passedClass);
It should work.
You're passing in the class, so you can operate on it directly.
void passThis(Class<?> passedClass) {
Transformers.aliasToBean(passedClass);
}
You also don't say function in Java. You might be thinking of JavaScript.
On another note, there is basically no point to using a generic class as you have it in your example. Passing in simply (Class passedClass) would work just as well.
So the question is why you went the generics route. It could be you want something more like this:
<T> T passThis(Class<T> passedClass){
return Transformers.aliasToBean(passedClass);
}
Just depends on what you are trying to accomplish.
I want to return from a Java method a reference to a Scala object. How can I do that?
My Scala objects are like this:
trait Environment
object LocalEnvironment extends Environment {...}
object ServerEnvironment extends Environment {...}
... and I want my Java method to be like this:
Environment getEnvironment() { return LocalEnvironment; } // DOES NOT COMPILE
Is there a way to do this?
While the $.MODULE$ method works, a slightly less jarring way to get Java-interop with Scala objects is to expose the object as a method on itself.
The Scala:
object LocalEnvironment extends Environment{
def instance = this
}
The Java:
Environment getEnvironment() { return LocalEnvironment.instance(); }
This works because under the covers, .instance() is implemented as a static method on class LocalEnvironment. There has been some discussion about Scala objects getting an "instance" method by default, for just this purpose.
{ return LocalEnvironment$.MODULE$; }
should work.
Edit: the reason why this works is that this is how Scala represents singleton objects. The class ObjectName$ has a field in it called MODULE$ that is populated with the single valid instance of that class. But there is also a class called ObjectName that copies all the methods as static methods. That way you can use it like Java (just call ObjectName.methodName) in most cases, and Scala gets to have a real class to pass around.
But when Java needs to pass the class around--not something normally done with a bunch of static methods, which is what object is designed to emulate in Java--you then have to know how Scala represents it internally.