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.
Related
I have a Kotlin object that delegates it's implementation, in my case to MutableSet<String> like so:
object MySet : MutableSet<String> by TreeSet<String>() {
init {...}
}
In Java I'd like to say something like MySet.contains. How can I do that?
object declares a singleton. Unlike Kotlin, you cannot use a type name to refer to its instance in Java. Therefore, the Kotlin compiler translates the singleton instance to a field called INSTANCE instead, so you can do:
MySet.INSTANCE.contains(foo);
in Java.
While you can probably find INSTANCE by chance, just by using the auto-complete in IntelliJ, the only place where I could find this officially documented is in the Calling Kotlin from Java page at the bottom of this section, which talks about calling static methods.
object Obj {
#JvmStatic fun callStatic() {}
fun callNonStatic() {}
}
In Java:
Obj.callStatic(); // works fine
Obj.callNonStatic(); // error
Obj.INSTANCE.callNonStatic(); // works, a call through the singleton instance
Obj.INSTANCE.callStatic(); // works too
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.
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.
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.
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).