Passing parameter information with { } - java

So you can do generic types with <> and you can pass objects with (). But what is it called when you pass information with {}, as in this example?
new Filter<CLDevice>() {
public boolean accept(CLDevice device) {
CLDeviceCapabilities caps = CLCapabilities.getDeviceCapabilities(device);
return caps.CL_KHR_gl_sharing;
}
}
Also does this work only for constructors or can any method make use of {} to gather data?
Is there any caveats associated with such code, like is it not performant?

What you are showing is not actually passing information (like passing an argument to a method), it's passing behavior.
Because up until Java 7 no lambdas existed, in order to pass behavior you always needed a class (after all in the java world everything a class). The syntax you are showing, is the syntax for an anonymous inner class. This syntax is used as a shortcut when you don't need/want to create a new class file, but just need to pass some behavior.
Note that you could just as easily use the same syntax if you had to implement (behavior passing) more than one method - something you could not do with Java 8 lambdas.

In this case you are providing an implementation via an anonymous class for a Single Abstract Method (SAM) interface or functional interface.

In java { and } define scope. There are various type of scopes for example class, method, block.
In your example your are creating a anonymous class.

So you can do generic types with <>.
You can pass objects with ().
What is it called when you pass information with {}, as in this example
With {} you create a body of a method or an anonymous class/method/object.. here your code is defining an anonymous method.

Related

Scala: how to implement a java interface that contains scala "typed" classes without their type parameters

This is a tricky one - I have a java interface that I want to implement in scala:
public interface Foo {
public void bar(scala.Array arr);
}
Is it even possible to implement in scala? when I try:
class FooImpl extends Foo {
override def bar(arr: Array[_]): Unit = ???
}
I get:
Error:(13, 7) class FooImpl needs to be abstract, since method bar
in trait Foo of type (x$1: Array)Unit is not defined
(Note that Array does not match Array[_]. To implement a raw type, use
Array[_])
class FooImpl extends Foo {
The error message is giving you the answer for any generic type other than Array (after replacing the name, of course):
To implement a raw type, use Array[_]
"Raw type" is what Java calls a generic type used without a type parameter and e.g. https://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html explains why you should not use them except to interface with now horribly obsolete pre-Java-5 code. So if it is at all an option, you should fix the Java interface in the first place.
Now, why does this not work for Array? It's a special type, which is really built into compiler. Its instances are real JVM arrays, which don't have a common type in Java. So when it's used in Scala code, the compiled bytecode doesn't use scala.Array at all. I guess that it only exists as a JVM type (unlike e.g. scala.Any or scala.Null) to put the static methods there, but all instance methods are defined as throw new Error(). It seems the error message didn't take this unique case into account.
So, the answer is: no, it can't be implemented in Scala, as far as I am aware. But it can't be non-trivially implemented in Java either. And even for trivial implementations, you'd run into the same issues when trying to write code using it.
To make the code work you either have to
Make the FooImpl declaration as abstract class
Implement the bar method
because "Java interfaces don’t implement behaviour".
For your reference see this page.

Lambda expressions mechanisms in Java [duplicate]

This question already has answers here:
Lambda expression vs method reference implementation details
(3 answers)
Closed 5 years ago.
I just read in a book that when a lambda expression is assigned to a functional interface, then that sets the "target type" for the lambda and an instance of that type (that is, the functional interface's type) is created with the lambda expression used as implementation for the abstract method in the functional interface.
My question: If so, then does that mean lambdas aren't really standalone methods and as such a new type of element brought into the language, but are simply a more compact way for expressing an anonymous class and as such merely are added facility (just like generics) on the compiler's side?
Moreover, how do method references comply with that, in particular, static methods which are not associated with any objects? For example, when a method reference to an instance method is assigned to a functional interface then the encapsulating object for that method is used, but what happens in the case of a static method - those are not associated with any object.. ?
If so, then does that mean lambdas aren't really standalone methods and as such a new type of element brought into the language,
Correct, lambdas are compiled into normal methods with a synthetic name
but are simply a more compact way for expressing an anonymous class and as such merely are added facility (just like generics) on the compiler's side?
No, it's not only on the compiler side. There are is also code in the JVM involved, so that the compiler doesn't have to write class files for the lambdas.
Moreover, how do method references comply with that, in particular, static methods which are not associated with any objects?
Method references are not different from lambdas: at runtime there has to be an object implementing the functional interface. Upon calling the "SAM" of the object this method will call the referenced method.
For example, when a method reference to an instance method is assigned to a functional interface then the encapsulating object for that method is used,
No, it can't be used. Let's take the following example using a System.out::println method reference:
Arrays.asList("A", "B").forEach(System.out::println);
List<E>.forEach() expects a Consumer<? super E> which defines the method void accept(E e). The compiler need to generate byte code and other information in the class file so that at runtime the JVM can generate a class implementing Consumer<E> with a method void accept(E e). This generated method then calls System.out.println(Object o).
The runtime generated class would look something like
class $$lambda$xy implements Consumer<Object> {
private PrintStream out;
$$lambda$xy(PrintStream out) {
this.out = out;
}
void accept(Object o) {
out.println(o);
}
}
Your question from the comment: "Why not directly assign to instance and its method?"
Let's expand the example a little bit:
static void helloWorld(Consumer<String> consumer) {
consumer.apply("Hello World!");
}
public static void main(String[] args) {
helloWorld(System.out::println);
}
To compile this, the compiler has to generate bytecode that creates an object implementing Consumer<String> (so it can pass the object into helloWorld()). That object somehow has to store the information that upon calling it's accept(x) method it has to call println(x) on the System.out PrintStream.
Other languages may have other names or concepts for this kind of objects - in Java the established concept is "an anonymous class implementing the interface and an object of that anonymous class".
How does the object store this information? Well, you could invent some super cool new way to store this information. The Java Language designers decided that an anonymous class would be good enough - for the time being. But they had the foresight that if someone came along with a new idea to implement it in a more efficient way, this should be easy to integrate into the Java ecosystem (Java compiler and JVM).
So they also decided to create that anonymous class not at compile time but to let the compiler just write the necessary information into the class file. Now the JVM can at runtime decide on what the optimal way to store the information (calling the correct method on the correct object) is.
For example, when a method reference to an instance method is assigned
to a functional interface then the encapsulating object for that
method is used, but what happens in the case of a static method -
those are not associated with any object..
That depends on context. Let say we have a static Utils#trim(String) method that will obviously trim given string.
And now, lest have a List<String> list and lets have some strings in it. We can do something like this:
list.stream().map(Utils::trim).collect(Collectors.toList());
As you can see, in given context, we are using lambda static method reference in order to use every string in list as input argument of Utils::trim method.

Extend a class using generics for a specific type

I am wondering. I have a class OccList<T>. I am fine with OccList holding any object, but I want to do more if T is a String, or if T is an integer.
Is there any way I can use the same name while doing it? My solution thus far is to create a new class class StringOccList extends OccList<String>. Optimally I'd like to be able to use OccList<String> and let java create the appropriate class according to the type used, much like method signatures work. Is it possible? Is there a better solution?
It has to be a different class, unless you want the added functionality to be part of the base class.
Think about it; lets say you have a method printAll that calls System.out.println on all the contents of the list. Where is the method going to go?
You only want the method to be callable if it's a String. Then it cannot be part of the base class (because otherwise it would be defined in the base class), so you need to use a different class like StringOccList
It's okay if the method is callable in the base class. You can write it so that (in the case of String) it calls T.toString on all members, or you can have the method throw an exception if T isn't the appropriate type.
That's what it means to be "generic" - the class will work for any kind of inner type. If it won't work for any kind of inner type, then it's not generic anymore!
Yes, you could make use of the one place where Java infers types, that is method returns. Imagine you want an OccList of String, but you don't want to do this
OccList<String> list = new OccList<String>();
Well, then you just write up a method to do that. Like this:
public static <E> OccList<E> newOccList(){
return new OccList();
}
and invoke it like this:
OccList<String> stringList = newOccList();
OccList<Integer> integerList = newOccList();
OccList<File> fileList = newOccList();
It'll work for any generic type you need.
This is used in the Google Guava library, please refer to it here

new Object { } Construct

In Java, the standard way to create an object is using
MyClass name = new MyClass();
I also often see the construct
new MyClass() { /*stuff goes in here*/ };
I've been looking online for a while and can't find a good explanation of what the second construct style does or how it does it.
Can someone please explain how and why you would use the second construct?
This construct makes actually two things: 1) It declares an anonymous class which extends the class you use in the constructor and 2) creates an instance of this anonymous class.
Edit: When using such a construct you can observe the anonymous class by looking at the generated .class files. There is the normal MyClass.class file and another one for each anonymous subclass: MyClass$1.class for the first and so on.
You would use the second construct in the case that you want to make an anonymous class. if you have a method that takes a callback as an argument, you might want to specify the implementation of the callback inline as opposed to giving it a name and putting it in a separate file or declaring it elsewhere in the same file.
There's also a trick called double brace initialization where you can get around not having syntax for literal maps and lists by using anonymous classes, like this:
Map map = new HashMap() {{put("foo", 1); put("bar", 2);}};
Here the nested braces create an instance initializer. The object bound to map is not a HashMap, its class is an anonymous class extending HashMap. (That means if you have a PMD rule about classes needing to declare serial uids then it will complain about this.)
Double-brace initialization is a fun trick to know but don't use it in real code. It's not safe to pass around the map created like this, because the inner object keeps a reference to the outer instance so if anything in the program holds onto a reference to the map it keeps the outer object from getting garbage-collected. There are also problems with serialization.
As others have already said, it creates an instance of an anonymous class, subclassing Class. Here's an example how it is commonly used:
panel.addMouseListener(
new MouseAdapter () {
#Override
public void mouseEntered(MouseEvent e) {
System.out.println(e.toString());
}
}
);
The above code creates an instance of an anonymous class which extends MouseAdapter. In the anonymous class the method mouseEntered has been overridden to demonstrate that the anonymous class works basically as any other class. This is very convenient and common way to create (usually simple) listeners.
Second construction creates an instance of anonymous class which is a subclass of Class.
If you want to new a object by a protect constructor from another package, you can use:
new Foo() {};
otherwise you will get an access error. It equals anonymous subclass inherited from Foo class.
From jdk8 onwards you may have seen different syntax seems like creating an objects while using lambda expressions.
NOTE: Lambda expressions don't get translated into anonymous inner classes, they use invoke dynamic that was introduced in Java 7 to execute functional methods.
For Example:
public class LambdaSample {
public static void main(String[] args) {
//If implementation is only one statement then {} braces are optional
Runnable oneLineImplRunnable = ()->System.out.println("This is one line lambda expression");
//Multiple statements in the implementation then {} braces are mandatory
Comparator<StudentTest> stdComparator = (StudentTest s1,StudentTest s2)->{
if(s1.getFirstName().equals(s2.getFirstName())) {
return s1.getLastName().compareTo(s2.getLastName());
}else {
return s1.getFirstName().compareTo(s2.getFirstName());
}
};
}
}

Uninstantiated Anonymous Classes in Java

It's been about 6 years since I've written Java, so please excuse the rust.
I'm working with a library method that requires that I pass it Class objects. Since I'll have to invoke this method a dynamic number of times, each time with a slightly different Class argument, I wanted to pass it an anonymous class.
However, all the documentation/tutorials I've been able to find so far only talk about instantiating anonymous classes, e.g.:
new className(optional argument list){classBody}
new interfaceName(){classBody}
Can I define an anonymous class without instantiating it? Or, perhaps more clearly, can I create a Class object for an anonymous class?
Unfortunately, there's no way you can dodge the instantiation here. You can make it a no-op, however:
foo((new Object() { ... }).getClass());
Of course, this might not be an option if you have to derive from some class that performs some actions in constructor.
EDIT
Your question also says that you want to call foo "each time with a slightly different Class argument". The above won't do it, because there will still be a single anonymous inner class definition, even if you put the new-expression in a loop. So it's not really going to buy you anything compared to named class definition. In particular, if you're trying to do it to capture values of some local variables, the new instance of your anonymous class that foo will create using the Class object passed to it will not have them captured.
short answer
you cannot (using only JDK classes)
long answer
give it a try:
public interface Constant {
int value();
}
public static Class<? extends Constant> classBuilder(final int value) {
return new Constant() {
#Override
public int value() {
return value;
}
#Override
public String toString() {
return String.valueOf(value);
}
}.getClass();
}
let's creating two new class "parametric" classes:
Class<? extends Constant> oneClass = createConstantClass(1);
Class<? extends Constant> twoClass = createConstantClass(2);
however you cannot instantiate this classes:
Constant one = oneClass.newInstance(); // <--- throws InstantiationException
Constant two = twoClass.newInstance(); // <--- ditto
it will fail at runtime since there is only one instance for every anonymous class.
However you can build dynamic classes at runtime using bytecode manipulation libraries such ASM. Another approach is using dynamic proxies, but this approach as the drawback that you can proxy only interface methods (so you need a Java interface).
You can only reference an anonymous class ONCE. If you do not instantiate it there, you cannot instantiate it since you do not have a name for it.
Hence I believe that anonymous classes can only be used in conjunction with a "new BaseClass()".
In your situation you would pass a BaseClass object to your method doing the work, and instantiate the anonymous object in the source code when you need the object to pass.
You can't access the Class object of an anonymous class without instatiating it. However, if you only need access to the class, you could define local classes within your method and refer to these using the ClassName.class literal syntax.
You can assume the name of an anonymous class and call Class.forName("mypackage.MyBaseClass$1") to get a handle to an anonymous class. This will give you the first anonymous class defined in your MyBaseClass, so this is a rather fragile way to refer to a class.
I suspect whatever you are trying to do could be done a better way. What are you really trying to achieve? Perhaps we can suggest a way which doesn't require you to pass a Class this way.
You can access the class object of an anonymous class by calling .getClass() on it immediately after creation. But what good would that do?
I think the key is in this part of what you said:
I'm working with a library method that requires that I pass it Class
objects.
Why does it want you to pass it Class objects? What does this library do with the Class objects you pass it? Instantiate objects? But if so, what constructor does it use and how does it decide what arguments to pass? I don't know what library you are using or what it does, but I would guess that it always creates objects using the no-argument constructor. However, that will not work for anonymous classes anyway, since they have no public constructor (and in any case, to instantiate any non-static inner class, a reference to the outer instance must be provided, so there is no no-argument constructor).

Categories

Resources