Sorry if this is very specific...
I am looking at Javapoet's implementation of AnnotationSpec.get(Annotation). It recursively clones an annotation so that you can copy it to another element. In my case, I am trying to copy an #OpenApi annotation from one method to another.
The issue is caused by the annotations being written in kotlin. Anywhere the annotation needs a class, it is using KClass<*>. Javapoet only handles Java types, like Class<?>. From Java, I can say if (o instanceof Class || o instance of KClass) no problem.
However, there's also code that says o.getClass().isArray() but, from what I can tell, kotlin annotations use Array<*> for arrays, so that check is failing. The actual type appears to be com.sun.proxy.$Proxy54 when I inspect it, but I have no idea what that is.
How do you detect if an object is an kotlin array from Java? Can this be converted to a Java array? Is there some universal way to make kotlin annotations appear as java annotations using Class and built-in arrays and so on?
Kotlin arrays and Java arrays are the same thing at the VM level. Array<*> is Kotlin's syntax for arrays, but the objects are the same thing. .isArray should work.
The proxy objects are typical for what you get when you call getClass on annotation objects in Java or Kotlin. You likely need to use annotationType instead of getClass.
Related
I'm currently learning java in order to make an app on android and I checked that swift has a structure that stores information in memory. I'd like to know, if in java this type of object exists, because the class storage the reference on the memory. Also I checked that Kotlin has a data class, does java have a similar object?
No, there is nothing like that, but there are tools, that try to mimic this behavior, for example lombok. Using #Data annotation we're getting default constructor, getters, setters, toString, equals, hashCode. We can fine-tune it by using annotations like #Getter, #NoArgsConstructor etc.
Neither Java nor Kotlin have anything similar to those Swift types you are talking about. Assignment always copies references to an object, rather than the object itself. What Kotlin's data classes do is that they create a copy method (among other things) that allows you to explicitly make a copy of an object, but you still have to actually call the method.
val b = a // b and a point to the same object, even if it is a data class
val b = a.copy() // this is what you need to do to create a copy of a data class
Java assignment copies references, not objects, and the same is true for Kotlin. There is no way around this, because it is a feature of the language itself. Copy constructors and methods (like what Kotlin's data class gives you) are the closest thing you have to such a feature. To get something like this in Java without having to manually write the code everytime, you could look into Project Lombok.
Starting with Java 14 you will have access to Record immutable class. It is similar in concept to data class in Kotlin.
How are templated methods implemented in C++?
I'm thinking about implementing templates in the JVM and have got a possible implementation thought out for templated classes, but am unsure on methods.
If, for example, you did:
class Test
{
public static boolean isIterable<T>(T variable)
{
return T instanceof Iterable;
}
}
System.out.println(Test.isIterable(new int[] { 0 }));
Would I create a version of Test that replied to int[]? (In my implementation, the class would be named as such: $g$Test$A_Java_lang_int)
Please ignore any problems with generics (such as only requiring boxed objects), as I intend to remove them.
I plan on creating these resolved templates dynamically, and keeping track of the number of references so I can remove them if they are not used. I believe this is how .Net manages it, although I'd be happy to be wrong here!
Would I create a version of Test that replied to int[]?
Essentially, yes. Templates in C++ are purely a compile-time mechanism that uses a (glorified) macro mechanism to generate code based on a template for each type with which it’s instantiated.
(C++ actually does a lot more due to the possibility of specialisation but this is the gist of it.)
I would suggest trying to do this staticly by generating the classes. You might find http://trove.starlight-systems.com/ interesting as it has a templating approach to generating its primitive collections. e.g. TintLongHashMap This doesn't rely on any language features.
I would suggest you work out how to do this staticly before trying to do it dynamicly which is much harder.
In Ruby, you can do "var1".constantize to get the actual variable var1.
Ruby also has Model.Send("method name, parameters can be here, etc"), and it would be the same as actually calling that method.
What I want to do.. is... kinda tricky... I want the string "var1 == var2" to be converted to actual variables in my java app, then evaluated.
Is there a way to do this?
Have you considered using JRuby?
As to your questions:
There is no peer to constantize that will allow for an eval like syntax where you can pass in a String and convert it to code in Java. You can do things like Class.forName to load a particular class from a String, but it doesn't sound that is what you are looking for.
You can use the Java reflection API to dynamically invoke methods on a class Check out Jakarta Commons BeanUtils for some utility methods that may help.
In Java, similar behaviour is achieved through the Reflection API. However, since Java is a compiled language, local variables' (within methods, constructors, parameters, etc) information is erased on compilation.
However you still have complete access to class names, hierarchies, methods and fields (class variables).
A good starting point is the Reflection API tutorial or the getClass() method of Object.
In Java if you want a dynamic lookup of variables, you would typically place them in a Map and lookup use the keys of that Map.
Can you explain what you are trying to do in more detail, I suspect what you are trying to do can be done simply a different way in Java.
So, I need to dynamically create (or inject) methods into an object that have a specific return type and method signature, because a Java tool we're using will be finding this methods via Reflection and checks for void type. Method names will be determined at runtime.
Using metaClass. = { ... } however adds a closure which doesn't show up as a regular method (even if it can be used as one) and also has a return type.
I can't modify the method finding code, and it it not Groovy-aware.
I can't use methodMissing() or invokeMethod() because the method needs to actually exist. If I could overload class.getMethods() I think it would be possible, but I can't figure out how.
Is there any way to do this in Groovy?
You could use AST Transformations to add the code at compile time, but it wont work on classes that you don't compile, so I'm guessing that probably wont work.
You could probably replace the object with a CGLIB based proxy. If you can be more specific about the code in question...
EDIT: A little more info. Groovy metaClass magic is not available in Java unless the Java code were to explicitly call groovyClass.invokeMethod("someMethod",args);. So there isn't a way to do what you're asking with MetaClasses. CGLIB maybe.
I'm working with Java 6's annotation processing, i.e. what can be found within javax.annotation.processing (not Java 5's APT).
I wonder what the conceptional difference between the various Element, Type, and Mirror classes is. As I don't really understand this, it's hard to efficiently program an annotation processor. There are various methods that 'convert' between these notions but I'm not really sure what I'm doing when using them.
So, for example, let me have an instance of AnnotationMirror.
When I call getAnnotationType() I get an instance of DeclaredType (which implements TypeMirror for whatever reason).
Then I can call asElement() on this one and obtain an instance of Element.
What has happened?
There is indeed on overlap between these concepts.
Element models the static structure of the program, ie packages, classes, methods and variables. Just think of all you see in the package explorer of Eclipse.
Type models the statically defined type constraints of the program, ie types, generic type parameters, generic type wildcards. Just think of everything that is part of Java's type declarations.
Mirror is an alternative concept to reflection by Gilad Bracha and Dave Ungar initially developed for Self, a prototype-based Smalltalk dialect. The basic idea is to separate queries about the structure of code (and also runtime manipulation of the structure, alas not available in Java) from the domain objects. So to query an object about its methods, instead of calling #getClass you would ask the system for a mirror through which you can see the reflection of the object. Thanks to that separation you can also mirror on classes that are not loaded (as is the case during annotation processing) or even classes in a remote image. For example V8 (Google's Javascript engine) uses mirrors for debugging Javascript code that runs in another object space.
This paper may help understanding the design of Java 6 annotation processing:
Gilad Bracha and David Ungar. Mirrors:
Design Principles for Meta-level
Facilities of Object-Oriented
Programming Languages. In Proc. of
the ACM Conf. on Object-Oriented
Programming, Systems, Languages and
Applications, October 2004.
The object of type javax.lang.model.element.AnnotationMirror represents an annotation in your code.
The declared type represents the annotation class.
Its element is the generic class (see http://java.sun.com/javase/6/docs/api/javax/lang/model/element/TypeElement.html for more information on that matter). The element might be the generic version of a class, like List, where as the declared type is the parametrized version, for instance List<String>. However I'm not sure it is possible to have annotations classes use generics and thus the distinction might be irrelevant in that context.
For instance lets say you have the following JUnit4 method:
#Test(expected = MyException.class)
public void myTest() {
// do some tests on some class...
}
The AnnotationMirror represents #Test(expected = NullPointerException.class). The declared type is the org.junit.Test class. The element is more or less the same as there are no generics involved.