How to implement Scala apply method in Java - java

I want to call some Java code from Scala code. I would like to use Scala's apply construct, so I can call it like this:
val led = OutPin(0)
instead of:
val led = new OutPin(0)
I naively implemented an additional apply method in my Java code like this:
public class OutPin {
public OutPin(int pinNumber) {
}
public OutPin apply(int pinNumber) {
return new OutPin(pinNumber);
}
}
This does not make my Scala code (first line above) compile, and instead gives me an error:
Object OutPin is not a value
What is the correct way to implement Scala's apply method in Java?

Your problem is not with the apply method per-se, but with trying to implement a Scala singleton object in Java.
I think (but am not certain) that this is very difficult, perhaps even impossible, by design.
Consider a very, very simple case:
object Obj;
This compiles to two JVM bytcode files, Obj$.class and Obj.class. In theory, it should be easy to just inspect the bytecode of those two classes, and reexpress the same thing in Java. The basic structure of Scala singleton objects is very, very simple:
For a singleton object Obj, a Obj.class and Obj$.class must be generated
The Obj$ class must have a public final static field of type Obj$ called MODULE$, which will be initialized on class initialization refer to the singleton object. In Scala, calls to Obj.foo() get mapped to Obj$.MODULE$.foo() [...if Obj had a method called foo(), that is!]
The Java compiler doesn't know anything about these Scala generated class pairs, so for Java interop, the Obj class contains static functions that just forward to a call of a method of the same name and signature on Obj$.MODULE$.
That sounds complicated, but it's really not so much. It's trivial to write a pair of Java classes that goes this far. But the Scala compiler (2.10.3) still won't recognize the pair as constituting a Scala singleton. Diving into the bytecode of a Scala-compiler generated singleton, you'll see that there are details that are hard to express in legal Java. [Hint: javap -c -p -s -v <fully-qualified-class-name>]
For example, the final static MODULE$ field is initialized indirectly by the static initializer. The static initializer just constructs an Obj$ object, without directly assigning it. The assignment occurs within the private constructor. That's illegal in Java: blank static finals must be certainly initialized in the static initializer, and cannot be assigned in code (like the private constructor) that might potentially be called from outside the initializer and multiple times. The Scala compiler generates bytecode that respects the blank final semantics (because the private constructor is only called once), but exceeds the Java compiler's ability to verify those semantics. So this code would be rejected if expressed in Java.
Also, the Obj class (the version without the terminal dollar sign) includes an annotation of type ScalaSig, which looks quite complicated and would be hard to reproduce by hand (in Java or in Scala), at least for those of us unsure exactly how this annotation works.
I don't know exactly what the Scala compiler looks for before deciding to treat a pair of classes as a "value", that is a valid Scala singleton object, but Scala's designers have chosen not to make it easy, despite the simplicity of the basic scheme. Probably they wish to preserve the ability to reorganize how scala singleton objects translate to bytecode. Letting Java programmers synthesize scala singleton objects would effectively render the current scheme a permanent part of Scala's public API.
Note that writing an ordinary, non-singleton class whose instances have an apply(...) method and so can be called like functions is easy from Java and works fine. Here's a Java cat:
public class Cat {
public String apply( int i ) {
return "Meow: " + i;
}
}
Here's a use of Scala's sugared apply:
Welcome to Scala version 2.10.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_45).
Type in expressions to have them evaluated.
Type :help for more information.
scala> val Morris = new Cat;
Morris: Cat = Cat#6b4feafa
scala> Morris(8)
res0: String = Meow: 8

If you want an apply method that is usable in Scala you should implement it on the scala an side using object to wrap your java class with the same name of the class which instantiate it
object OutPin {
def apply(pinNumber :Int) = new OutPin(pinNumber)
}

The problem is that the Scala compiler says you must define two companion objects in the same file, otherwise you get the error:
Companions 'class OutPin' and 'object OutPin' must be defined in same file
Here is another approach that might work for you. If you define your Scala OutPin in a separate package, then it will work. For example:
Java class:
package base;
public class OutPin {
private final int i;
public OutPin(int i) {
this.i = i;
}
public int getI() {
return this.i;
}
}
Scala class:
package base.scala
object OutPin {
def apply(i: Int): base.OutPin = new base.OutPin(i)
}
Sample Scala client:
import base.scala.OutPin
object Client extends App {
val op = OutPin(1)
println(op.getI)
}
Running Client prints 1
To get access to the sugared apply you would have to import base.scala instead of just base. If it's really important to get the apply syntax it might be worth it.

Related

What is the difference between a constructor and a builder when using generics?

While programming in Java, I encountered the following problem.
when use Constructor: The following code works fine.
public class Generics<T> {
private T data;
public static <T> Generics<T> of(T data) {
return new Generics<>(data);
}
public Generics(T data) {
this.data = data;
}
}
when use builder: An error occurs saying that the Object type is provided as follows.
I used a builder provided by Project Lombok.
Why doesn't the builder generic in the code above work?
Evidently Lombok generates a static generic builder() method. You can specify the generic type of a generic static method using <T> before the method name, as in:
return Generics.<T>builder()
.data(data)
.build();
If you don't specify the generic type when you call builder(), you get a raw type, at which point generic type inference no longer works.
You need to explicitly add the generics: return Generics.<T>builder() - add that <T> and all will be well.
Explanation
Java is aggressively typed: Every expression and just about every part of an expression has an actual type; java does not allow things to remain in limbo until later; there's no such thing as 'an intermediate - eh, we'll see where it goes'.
That means Generics.builder(), as an expression, needs to be typed by the system. The builder class needs that <T> just the same (it's a Generics.GenericsBuilder<X> - where Builder is a static inner class of Generics, and is defined as public static class GenericsBuilder<X>.
Java cannot just jump to the conclusion that you intend for X and T to be the same type.
Looking ahead, it can figure out that X should be T 'automatically', without your involvement: It can either check the .data(data) invocation, given that the data method is defined in the builder as:
public GenericsBuilder<X> data(X data)
thus, whatever type data (the variable)might be (it'sThere, given that it's the parameter defined asT data`), and therefore, java can conclude that the X should be T.
Otherwise, java can look even further ahead, to build(), and notice that this returns X, and is being returned by a method whose return type is defined as T, thus also giving java the opportunity to say: Ah, X == T, right.
But that is not how java works. In large part because even figuring out what the .data method might mean is rather hard to do when the X of that builder you just made (the X in the declaration public static <X> Generics.GenericsBuilder<X> builder()) must be left in some sort of unknown limbo state for a while as the parser carries on with trying to figure out what the rest means. Given that java allows method overloading (2 different methods with the same name and the same number of params, but different param types, which could contain generics to boot) - it'd be a combinatorial explosion and means you can write java code that takes literally years to parse.
Hence, java does not work that way, it must determine what X is supposed to be solely from the expression Generics.builder(), and it clearly cant.
The solution is to just write it explicitly, using this somewhat exotic syntax: Generics.<T>builder().

How to use class name as type for method argument

I have recently run into a bit of trouble while trying to make one of my bukkit plugins version independent using reflection.
The thing is, I know how to make an instance of a class by using it's name, but I don't know how to make use of the class name as a type for a method or constructor parameter. In other words, I want to transform this:
public class Foo{
private Goat goat;
public Foo(Goat goat){
this.goat=goat;
}
Into something like this:
public class Foo{
private Class.forName("mypackage.Goat") goat;
public Foo(Class.forName("mypackage.Goat") goat){
this.goat=goat;
}
Honestly I don't know if it's even possible, but it would help a lot in making my development faster.
EDIT:
My situation is a bit more complicated than the one I presented before. That's the reason I can't actually use generics. The 'Goat' type I illustrated above is actually a class inside a package unknown to me, so I only know the class name. Therefore, I have to make use of the Class.forName method along with a small algorithm that detects the current bukkit version and appends it to the package name I already know, so net.minecraft.server would become net.minecraft.server.v1_8_R1
In other words, I only know the class name at runtime. I know, I suck at explaining...
Updated Answer:
You've clarified in the comments that you only know the type name at runtime.
The type of the field (and constructor parameter) goat is set at compile time. The only way to use runtime information to create a Foo class is to do exactly that: Generate it at runtime. There's no mechanism for declaring a placeholder that will get filled in by a string later.
If you absolutely need to do that, some prior art you could call on would be Tomcat (which compiles JSPs on-the-fly) and Vert.x (which generates classes on-the-fly). It's going to be non-trivial (unless you're just shelling out to javac, of course).
Original Answer:
You can do this with generics:
public class Foo<T> {
private T goat;
public Foo(T goat){
this.goat=goat;
}
}
Usage:
Foo<Goat> f = new Foo<>(); // Or new Foo<Goat>() (earlier Java versions didn't support the <> form)
Now, f expects goat to be a Goat.
It's just like when you're using something from the collections framework:
List<String> strings = new List<String>();
List<Date> dates = new List<Date>();
// ...

how is scala type casting done in py4j?

Is there a way to do type casting like it is done is scala/java when using py4j to trigger jvm?
Basically, I would like to translate this:
someOtherTypeInstance.asInstanceOf[RDD[Any]]
Into something like:
someOtherTypeInstance = gateway.jvm.getSomeOtherTypeInstance()
someOtherTypeInstance.asInstanceOf(gateway.jvm.RDD[Any]) // don't know how to deal with generics
Py4J does not generally require type casting because of its heavy use of reflection.
If you call a method on an object, Py4J will use the JVM reflection facilities to find this method in the class hierarchy of the object no matter what the advertised type of the object is. Similarly, when you pass an object to a method, Py4J will try to find the closest method signature by inspecting the class hierarchy and implemented interfaces of the object.
For example, this code is perfectly valid in Py4J:
// Java code
public class TestTypes {
public void method1(Foo param1) {}
public Object getObject() { new Foo() }
}
// Python code
myJavaObject = java_gateway.jvm.TestTypes()
obj = myJavaObject.getObject()
// no need for type casting
myJavaObject.method1(obj)
If you need type casting for other scenarios (I don't know much about Scala), you should fill a feature request.

Difference between Reflection and Late Binding in java with real time examples

While studying Java tutorials, Reflection and Late Binding have confused me. In some tutorials, they have written that they are both the same, and that there isn't any difference between Reflection and Late Binding. But other tutorials say that there is a difference.
I am confused, so can someone please explain what Reflection and Late Binding are in Java, and if posible, please give me some real world examples of both.
Thanks..
Java uses late-binding to support polymorphism; which means the decision of which of the many methods should be used is deferred until runtime.
Take the case of N classes implementing an abstract method of an interface (or an abstract class, fwiw).
public interface IMyInterface {
public void doSomething();
}
public class MyClassA implements IMyInterface {
public void doSomething(){ ... }
}
public class MyClassB implements IMyInterface {
public void doSomething(){ ... }
}
public class Caller {
public void doCall(IMyInterface i){
// which implementation of doSomething is called?
// it depends on the type of i: this is late binding
i.doSomething();
}
}
Reflection is used instead to describe code which is able to inspect other code, ie. to know which methods or attributes are available in a class, to call a method (or load a class) by name, and doing a lot of very interesting things at runtime.
A very nice explaination of reflection is here: What is reflection and why is it useful?
Late binding (also known as dynamic dispatch) does not need reflection -- it still needs to know which member to dynamically bind to at compile-time (i.e. the signature of the member is known at compile-time), even though the binding to overridden members happens at run-time.
When doing reflection, you don't even know which member you're using (not even the name is known at compile-time, let alone the signature) -- everything happens at run-time, so it's a lot slower.
Real world examples:
If you build your project with jdesktop 0.8, but ship with jdesktop 0.9, your code will still use the 0.9 features, because it takes advantage of late binding, i.e. the code that your code calls is the version that is loaded by the class loader, irrespective of the version that it was compiled against. (This is as opposed to linkers, which embed the compile-time version of the called code into the application.)
For reflection, let's say you are trying to target Java 1.5 and 1.6, but want to use tab components in 1.6 if they are available, then you'll check for their presence by using reflection on the JTabbedPane class to find the setTabComponentAt method. In this case you're building against Java 1.5, which doesn't have those features at all, so you can't call them directly or the compile will fail. However if on the end-user's system you find yourself running against 1.6 (late binding comes into play here) you can use reflection to call methods that didn't exist in 1.5.
They are related; many uses of reflection rely on late binding to be useful, but they are fundamentally different aspects of the language and its implementation.
One important issue which is addressed by "Late Binding" is the polymorphism, i.e. that the call of the proper overriden method along your class hierachy is determined during the run-time, not during compilation. Reflection is the feature to gather and manipulate information about your objects during run-time. E.g. you can get all attributes or method names of an object using its 'Class' attribute during the runtime and call those methods or manipulate its attributes.
In following code you can dynamically create a new object by the means of reflection (see how the constructor is retrieved and accessed using a Class, instead of using simply something like object obj = new MyClass( "MyInstance" ) ). In a similar way it is possible to access other constructor forms, methods and attributes. For more information about reflection in java visit: http://java.sun.com/developer/technicalArticles/ALT/Reflection/
... in some method of some class ...
Class c = getClass();
Constructor ctor = c.getConstructor( String.class );
Object obj = ctor.newInstance( "MyInstance" );
I have to disagree with most of the responses here -
Everyone calls what Java does in terms of zeroing in on a method implementation at runtime as late binding, but in my opinion its not correct to use the term late binding for what java does.
Late binding implies absolutely no checks on a method call at compile time and no compilation errors if the method does not exist.
Java however will throw a compile error if the method does not exist somewhere in the type hierarchy of the type qualifying the method call (being somewhat approximate when describing the behavior here). This is not pure traditional late binding.
What Java does in a normal non private non final non static method call would be better termed as dynamic dispatch.
However if we use reflection in Java, then Java does perform pure late binding as the compiler simply cannot verify if the called method exists or not.
Here is an example:
class A
{
public void foo()
{
System.out.println("Foo from A");
}
}
class B extends A
{
public void foo()
{
System.out.println("Foo from B");
}
}
public class C
{
public static void main(String [] args)
{
A a=new A();
B b=new B();
A ref=null;
Class ref1 = null;
ref1 = b.getClass();
ref.foo1();//will not compile because Java in this normal method
//call does some compile time checks for method and method
//signature existence. NOT late binding in its pure form.
try {
ref1.getMethod("foo1").invoke(null); //will throw a
//NoSuchMethodException at runtime, but compiles perfectly even
//though foo1 does not exist. This is pure late binding.
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

How can I pass a Scala object reference around in Java?

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.

Categories

Resources