How to use to #file:JvmName in anotations [duplicate] - java

I want to load a resource in a top level function using Class.getResourceAsStream().
Is there any way to get a reference to the class that the top level function will be compiled into so that I can write, for example
val myThing = readFromStream(MYCLASS.getResourceAsStream(...))

Another way I found is to declare a local class or an anonymous object inside a top level function and to get its enclosingClass:
val topLevelClass = object{}.javaClass.enclosingClass
Note: to work, this declaration should be placed on top level or inside a top-level function.
Then you can use the topLevelClass as a Class<out Any>:
fun main(args: Array<String>) {
println(topLevelClass) // class MyFileNameKt
}

With Java 7 you can get a reference to the current Java class from a top level function using
MethodHandles.lookup().lookupClass()

No, there is no syntax to reference that class. You can access it using Class.forName(). For example, if the file is called "Hello.kt" and is located in the package "demo", you can obtain the class by calling Class.forName("demo.HelloKt").

In the absence of a way to get a reference directly, I've fallen back on creating an anonymous object in the current package
val myThing = object: Any() {}.javaClass.getResourceAsStream(...)

As linters like detekt would flag anonymous classes as EmptyClassBlock you could also use something like
internal object Resources
fun resourceStream(name: String): InputStream {
return Resources.javaClass.getResourceAsStream(name)
}

Related

Kotlin syntax confusion: fun Foo.bar() = (...)

I'm confused on what the following line of code is supposed to be doing:
fun MyContext.req() = request as LaunchRequest
LaunchRequest is a Java class, and MyContext is a Kotlin data class. I've tried looking up examples of Kotlin code that use this syntax, but haven't found anything.
MyContext doesn't have a req() function, so is this just defining a new function for MyContext that returns a variable called "request" of type LaunchRequest?
It’s an extension function named req defined on the receiver MyContext. This technique is used to add new functions to existing classes without the use of inheritance. This concrete example req can be invoked on any object of MyContext.
If you have a reference of MyContext it may be used as follows:
val ctx: MyContext = ...
val req: LaunchRequest = ctx.req()
The as keyword is used to cast the variable request to LaunchRequest.
If the = in the function declaration also leads to confusion: it’s called function with expression body, which can be used to replace block bodies (enclosed in curly brackets) when the function contains a single expression like given in your code.
These are extension functions of Kotlin which help in improving a class's functionality without actually writing a lot of boilerplate code.The function could be also written as
fun MyContext.req(): LaunchRequest(){
return (request as LaunchRequest)
}
Another example of Extension function(to animate view)is:
fun View.animatePulsing() {
val animation = AnimatorSet()
....
....
animation.duration = 150
animation.start()
}
We can use this as:
txtView.animatePulsing()

How to pass nested scala object reference in Java?

There have been some questions answered on this before.
How can I pass a scala object reference around in Java
How can I use a Scala singleton object in Java?
But my problem is that I have nested scala objects, something like:
object Criteria {
object ActionCriteria {
case class Action (parameter: String) {
def this(parameter: String) = { this(paramerter) }
}
object Action {
def apply(parameter: String): Action = { apply(parameter) }
}
}
}
In java I then need to create a list of Actions. I have tried this... to no avail:
import Criteria.ActionCriteria.Action$
....
List<Criteria.ActionCriteria.Action$.MODULE$> actions = new ArrayList<>();
As well as a bunch of other combinations like adding $.MODULE$ with every object. Right now I am getting the following error:
error: cannot find symbol Criteria.ActionCriteria
List<Criteria$ActionCriteria$Action> actions = new ArrayList<>();
Seems to work fine. Found this with Scala REPL:
scala> classOf[Criteria.ActionCriteria.Action]
res1: Class[Criteria.ActionCriteria.Action] = class Criteria$ActionCriteria$Action
If you want the type of Action object, not case class (highly unlikely, but for the sake of completeness):
scala> Criteria.ActionCriteria.Action.getClass
res2: Class[_ <: Criteria.ActionCriteria.Action.type] = class Criteria$ActionCriteria$Action$
The difference is caused by Scala expecting Action to be a type in classOf[Action], so it returns the type corresponding to the case class. When you use Action in a context where a value is expected, it returns the singleton instance instead, so you can call standard Java method getClass to get the type of object Action.
In case you need other types:
Criteria$ cm = Criteria$.MODULE$;
Criteria.ActionCriteria$ cacm = Criteria.ActionCriteria$.MODULE$;
Criteria$ActionCriteria$Action$ cacam = Criteria$ActionCriteria$Action$.MODULE$;
Criteria$ActionCriteria$Action caca = new Criteria$ActionCriteria$Action("Foo");
Criteria.ActionCriteria$ is breaking the pattern here. Why? According to Iulian Dragos' comment under bug SI-2034 this is a special case:
since objects are "the equivalent of static" in the Java world, we
wanted to make it easier for Java code to use static inner classes.
When there's only one level of nesting, there's a guaranteed
companion: every top-level object gets a mirror class (if there isn't
one) that creates static forwarders to module methods (that's how one
can run a main method defined inside an object). Therefore, a
special case for one-level nesting: those classes use the flattened
name (without a $ suffix) as outer_name. So, Java code can say new Outer.Inner.
Summary
For every level of nesting other than first you replace . with $ in your class names
If the target type is also an object you add $ at the end
If you want an instance you add .MODULE$

Is runtime-compiled-class instantiation & usage possible in Java without reflection?

I would like to know if there exists any kind of library or workaround to use my runtime compiled classes ( I dynamically generate my classes, writing .java, then compiling them in .class all of this happens at runtime) without using a reflection library?
Loading using reflection I always have to work like this:
//path where my newly generated classes are
File file = new File("e:\\tmp");
// Convert File to a URL
URL url = file.toURI().toURL();
URL[] urls = new URL[]{url};
ClassLoader cl = new URLClassLoader(urls);
Class cls = cl.loadClass("eu.dataaccess.footballpool.TGoal");
// Create an instance of the class just loaded
Object o = cls.newInstance();
Method method2 = cls.getDeclaredMethod("getIMinute");
Object result2 = method2.invoke(o);
My question is if it's somehow possible to use at runtime
TGoal x = new TGoal();
and
x.getIMinute();
EDIT: It seems it is impossible to act the way I hoped to. I modify my question so: is it possible to load a whole package at runtime, in a way that the classes of the loaded package are able to communicate each other without the method.invoke, meanwhile the main activation of the package is done with the method invoke() ?
I tried without any luck, i have some "error: cannot find symbol", it seems the runtime-loaded classes can't communicate each other
If you're not using the reflection api you have to instantiate classes via the new operator. This requires having the class file at compile time. So it is not possible. If your class TGoal is implementing an Interface IGoal, then you can cast your Object o to IGoal. This enables you to work with your Object like with any other object without using the reflection api.
You can do
x.getIMinute();
by using interfaces, but AFAIK you cannot create new class instances without reflection.
Instead, to call methods of your dynamically created objects, you
can declare an interface:
public interface MinuteGetter{
public int getIMinute();
}
Your dynamic objects have to implement his, than you can do:
Class cls = cl.loadClass("eu.dataaccess.footballpool.TGoal");
// Create an instance of the class just loaded
MinuteGetter o = (MinuteGetter) cls.newInstance();
o.getIMinute();
If applying an interface to your code is not an option for you, you can try to give a try to AnonymousClassLoader. See this detailed post about it.
It work only on Java 7, and please note that I never used it, so how don't know if it offer better performance than reflection.
Are you sure you have to create the Code at runtime? The easiest way is to avoid this.
If the TGoal x = new TGoal() doesn't have to happen in this program, then create a main function in the generated code and start a second java application.

What do 'self' and 'new' mean in Ruby from Java perspective?

I'm looking over some open-source code and can't wrap my head around this snippet.
class Something
def self.smart
new.smart
end
def smart
"test"
end
end
class Other < Something
println Other.smart
Is the code trying to instantiate a new instance every time smart is called?
def self.smart
new.smart
end
is equivalent to static method, which can e accessed by using class name.
... static ... smart()
and
def smart
"test"
end
is equivalent to instance method, need object to access
... smart()
new is same as the in java, created an instance of class.
and the whole thing is equivalent to.
public static .... smart(){
new ClassName().smart();
}

Getting method via reflection

My previous post was not very clear, sorry for that. I will try to give a better example of what I am trying to do.
I have an Java application that will load .class files and runs them in a special enviroment (the Java app has built-in functions) Note: This is not a library.
That Java application will then display an applet, and I want to modify the variables in the applet.
The main class of the applet is called 'client'.
The Java application will load the applet by creating an new instance of class 'client'.
I already got access to the 'client' class. the Java application will put the applet in a variable:
Applet client = (Applet) loadedClientClass.newInstance();
So I did this:
Class<?> class_client = client.getClass();
I can now read and set the fields but the 'client' class will call a funation of an other class, like this:
otherClass.someVoid(false);
And if I try something like:
class_client.getDeclaredMethod("otherClass.someVoid",boolean.class);
It will fail, saying that the function can not be found.
'otherClass' is the direct class name, it is not a reference to a new instance of the class as far as I know.
Is there any way to get 'otherClass.someVoid'?
You're using getDeclaredMethod like a static method (expecting it to return methods from any class), but it only returns method from the class itself. Here's how you can call otherClass.someVoid(false).
Class<?> otherClass = Class.forName("com.xyz.OtherClass"); // Get the class
Method method = otherClass.getDeclaredMethod("someVoid", boolean.class);
// If the method is an Class (ie static) method, invoke it on the Class:
method.invoke(otherClass, false);
// If the method is an instance (ie non-static) method, invoke it on an instance of the Class:
Object otherInstance = otherClass.newInstance(); // Get an instance of other class - this approach assumes there is a default constructor
method.invoke(otherInstance, false);
If the class isn't initialized, the var someInteger doesn't exist. It's a member variable, so it only exists inside of instances of the class. So, you can't change it since it's doesn't exist. Now, if you made it a static variable, then you could change it.
Is there any way to change 'otherClass.someInteger' through the
'mainClass' class?
No.
But you can get it via OtherClass' class via Class.forName:
Class<?> theOtherClazz = Class.forName("OtherClass");
And then get the methods via theOtherClazz.getDeclaredMethod

Categories