The Java 7 Language Specifications say pretty early on:
"this specification does not describe reflection in any detail."
I'm wondering just that: how is Reflection implemented in Java?
I'm not asking how it's used, and I understand there might not be as specific an answer I'm looking for, but any information would be much appreciated.
I've found this on Stackoverflow, the analogous question about C#: How is reflection implemented in C#?
The main entry point of any Reflection activity is the Class class. From it you can get Method, Field, Class, Constructor, and Annotation instances.
If you look at the source code, you will notice that to retrieve any of the above, Java has to make a native call. For example,
private native Field[] getDeclaredFields0(boolean publicOnly);
private native Method[] getDeclaredMethods0(boolean publicOnly);
private native Constructor<T>[] getDeclaredConstructors0(boolean publicOnly);
private native Class<?>[] getDeclaredClasses0();
private native byte[] getRawAnnotations(); // get converted to Annotation instances later
The implementation is done in native C code (and/or C++). Each JDK might differ, but you can look up the source code if it's available and you have patience. Details on the OpenJDK source code can be found in this question.
Related
I have come across the #JvmSynthetic annotation in kotlin-stdlib, and I'm wondering what it is for, but, unfortunately, it is undocumented. (UPD: it was at that moment)
As far as I understand, applying it to a program element will add the synthetic modifier to the corresponding bytecode elements. As a consequence, the element becomes invisible from Java:
class MyClass {
#JvmSynthetic
fun f() { }
}
Somewhere in Java code:
MyClass c = new MyClass();
c.f() // Error: cannot resolve method f()
But the same elements are still visible in Kotlin code:
val c = MyClass()
c.f() // OK
Is hiding declarations from non-Kotlin sources a valid use of #JvmSynthetic? Is it the intended use? What are the other appropriate use cases?
Since #JvmSynthetic hides functions from Java, they cannot be overridden in Java either (and when it comes to an abstract member, the calls then result into AbstractMethodError). Given that, can I use #JvmSynthetic to prohibit overriding members of a Kotlin class in Java sources?
In plain Java, synthetic methods are generated by the javac compiler. Normally the compiler must create synthetic methods on nested classes, when fields specified with the private modifier are accessed by the enclosing class.
Given the following class in java:
public final class SyntheticSample
{
public static void main(final String[] args)
{
SyntheticSample.Nested nested = new SyntheticSample.Nested();
out.println("String: " + nested.syntheticString);
}
private static final class Nested
{
private String syntheticString = "I'll become a method!";
}
}
when the SyntheticSample class accesses the nested.syntheticString field, it is indeed calling a static synthetic method generated by the compiler (named something like access$100).
Even if Kotlin exposes a #JvmSynthetic annotation that is able to "force" the creation of synthetic methods, I advice to not using it in normal "user" code. Synthetic methods are low-level tricks made by the compiler, and we should never rely on such things in everyday code. I think it's there to support other parts of the standard library, but you should ask the JetBrains guys directly if you're curious (try on the official Kotlin Discussion Forum)
First, to answer what synthetic methods actually are, let's have a look at the Java language specification:
11. A construct emitted by a Java compiler must be marked as synthetic if it does not correspond to a construct declared explicitly or implicitly in source code, unless the emitted construct is a class initialization method (JVMS §2.9).
The #JvmSynthetic annotation does exactly that: prevent access from source code. The method will still appear in reflection and is then marked as synthetic.
More precisely, from the Kotlin documentation (emphasis mine):
#JvmSynthetic
Sets ACC_SYNTHETIC flag on the annotated target in the Java bytecode.
Synthetic targets become inaccessible for Java sources at compile time while still being accessible for Kotlin sources. Marking target as synthetic is a binary compatible change, already compiled Java code will be able to access such target.
This annotation is intended for rare cases when API designer needs to hide Kotlin-specific target from Java API while keeping it a part of Kotlin API so the resulting API is idiomatic for both.
As described in the last paragraph, #JvmSynthetic is a tool for API design, which lets a library writer avoid automatic generation of Java equivalents. Probably the most popular use cases are Kotlin-only features, such as operator overloading, componentN() methods or properties, which may have a more idiomatic way to be exposed in Java.
It is noteworthy that the target of this annotations are property setters/getters, functions and fields -- basically everything that translates in Java to a method.
#Target([
AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER,
AnnotationTarget.FIELD])
annotation actual class JvmSynthetic
What are the caveats that a developer should be aware of while writing reflective code that works both with Java and Kotlin?
For example, I have an existing library that uses reflection and it works well with Java. However, when I use the same with Kotlin, my reflective code doesn't seem to pick up the annotations on fields.
Here are some of the differences that I noticed.
1. Acquiring a Class instance
// Example 1.1 - Java
Class<?> userClass = User.class; // From a class name
userClass = userInstance.getClass(); // OR from an instance
Getting a Java class instance in Kotlin
// Example 1.2 - Kotlin
val userClass = userInstance.javaClass // From an instance
I'm unable to use the .class facility or the .getClass() method in Kotlin as we do in Java.
2. Delegates
When I use delegated properties in a Kotlin class, the properties that I retrieve have the $delegate suffix. This is a bit contrary to the fields that we get in Java (I do understand Kotlin does not have fields, only properties). How does this affect meta-programming?
However, with delegates I see that most of the methods retain their behavior as they do in Java. Are there any other differences that I have to be aware of?
Making Java and Kotlin interoperable for me would require understanding about 1 discussed above, plus other limitations / differences that Kotlin brings to meta-programming.
For example, I have an existing library that uses reflection and it works well with Java. However, when I use the same with Kotlin, my reflective code doesn't seem to pick up the annotations on fields.
Can it be because the fields are private now?
Anyway, there are issues with annotations on fields at the moment, this will be fixed in on of the upcoming milestones.
Some other relevant issues:
https://youtrack.jetbrains.com/issue/KT-5967
https://youtrack.jetbrains.com/issue/KT-4169
https://youtrack.jetbrains.com/issue/KT-3625
I'm unable to use the .class facility or the .getClass() method in Kotlin as we do in Java.
Only the syntax is different: javaClass<C>() works exactly the same as C.class, and x.javaClass does the same thing as x.getClass()
When I use delegated properties in a Kotlin class, the properties that I retrieve have the $delegate suffix.
Minor correction: the fields have the $delegate suffix, not the properties.
However, with delegates I see that most of the methods retain their behavior as they do in Java. Are there any other differences that I have to be aware of?
The docs here give you a detailed description of how delegated properties are implemented.
Making Java and Kotlin interoperable for me would require understanding about 1 discussed above, plus other limitations / differences that Kotlin brings to meta-programming.
The more your Kotlin code resembles Java code, the smaller is the difference from the reflection point of view. If you write idiomatic Kotlin, e.g. use default parameter values, traits, properties, delegates, top-level functions, extensions etc, the classes you get differ from idiomatic Java, otherwise they are closely aligned.
I checked the source code of Object class where I found that method declaration of getClass() was
public final native Class<?> getClass();
And the declaration of hashCode() was
public native int hashCode();
Why are these two methods native methods in the class and how can I get the source code of those methods?
You can find the complete source code of the native methods here
I hope this will work for you.
These are native methods, because it has to interact with the machine. Here machine dependent code is written in the C language, which is not coming with the source package or in rt.jar of the lib location of the Java Runtime Environment (JRE).
One more reason for being native is possibly for the performance reasons. Due to the C level programming performance may be improved, hence they may have written the native code in the C language.
The methods are native because they concern native data. The hashCode method returns an integer value dependent on the internal representation of a pointer to an object on the heap. The getClass method must access the internal vtbl (virtual function table) that represents the compiled program's class hierarchy. Neither of these is possible with core Java.
Source code for Object class can be found here
This source contains implementation of getClass() method (See line 58). hashCode is defined as a function pointer JVM_IHashCode (See line 43).
JVM_IHashCode is defined in jvm.cpp. See code starting from line 504. This in turn calls ObjectSynchronizer::FastHashCode which is defined in synchronizer.cpp. See implementation of FastHashCode at line 576 and get_next_hash at line 530.
Probably, the methods are native for performance and due to practical issues w.r.t implementation.
For e.g., From javadocs, hashCode is typically implemented "by converting the internal address of the object into an integer". This internal address is not available via java sdk and will have to be implemented as a native method.
Please read Is it possible to find the source for a Java native method?. Also read this blog post Object.hashCode implementation. It gives more details. But makes a wrong assertion that hashCode is not generated from object's identity.
Hope it helps.
The information for these is in the header (for the class) or elsewhere (for the hashCode) This is not something you can implement in Java. The source for these methods is in the source for the JVM. e.g. you can download the source for OpenJDK.
I have an Android application (java) that was working fine when compiled with the Android 1.6 SDK using the following code from the android.provider.Contacts class:
Uri baseUri = Contacts.Phones.CONTENT_FILTER_URL;
When the 2.0 SDK came out, the android.provider.Contacts class was depreciated and replaced with android.provider.ContactsContract. In order to get one program to work on both 1.6 and 2.0, I compiled under 1.6 with the following change:
Uri baseUri = Contacts.Phones.CONTENT_FILTER_URL;
…
try {
Class<?> c = Class.forName("android.provider.ContactsContract$PhoneLookup");
baseUri = (Uri) c.getField("CONTENT_FILTER_URI").get(baseUri);
}
catch (Exception e) {
}
Since I was compiling under 1.6, I could not import android.provider.ContactsContract since it is a class known only to 2.0. Is this considered reflection and to what degree?
Added Comment: After reading the "Reflection" chapter of "The Java Programming Language" (which I should have done first), I mostly now understand what you can do with reflection but a concise definition of reflection is not easy to come by. Your answers have helped to clarify what prompted my question - that once a class has been reflected on, and an instance of the class created using reflection, you can interact with the instance as if the class was new'ed.
Here is my meager attempt at a concise definition that is far from perfect and I am sure I will need to revise as I learn more:
Reflection is the indirect, dynamic inquiry, manipulation or invocation of class objects using class objects contained in java.lang.reflect or the Class or Package classes that requires initially accessing the class using a fully qualified string name.
I believe that is the very definition of Java reflection (more on Android reflection for multiple-version compatibility). I'm not sure what you mean by "to what degree"; it just is.
Dynamically asking for the availability of a method is a form of reflection, yes.
It's reflection.
If CONTENT_FILTER_URI is a final static field, then you should use get(null) instead of get(baseUri) because you are not invoking an object.
Edit
I was a bit confused by your code. As I understand your snippet, first you assign Contacts.Phones.CONTENT_FILTER_URL to URL baseUri, then you reflect the CONTENT_FILTER_URI field on the PhoneLookup class and read that fields value from the URL instance stored in baseUri - just to assign the value to baseUri again !? Typo or room for improvement?
This is a very good article on strategies, reflection and other more sophisticated things, for using new APIs while remaining compatible with older platforms:
http://android-developers.blogspot.com/2009/04/backward-compatibility-for-android.html
Lamdbaj allows the definition of closures in the Java language, various examples can be found
here
My question is regarding the underlying Java mechanisms at use, for instance, to define the println closure, the following code is used:
Closure println = closure();
{ of(System.out).println(var(String.class)); }
This closure can be subsequently executed via:
println.apply("foobar");
I am curious as to what mechanisms in Java would allow the call to of(...).println(...) to become associated with the println instance itself.
Naturally, the lambdaj source code is available to read but I was hoping for a slightly higher level explanation if anyone has one. My reflection skills go as far as a bit of introspection and executing methods dynamically.
I am Mario Fusco and I am the main developer of the lambdaj library.
First of all I would like to clarify something: lambdaj is not intended to replace any functional language. As I said last week in my speech at the Jug of Zurich if you have a chance to use Scala, go for it and never look back. Here you can find a resume of my speech where it is clearly stated that:
http://ctpjava.blogspot.com/2009/10/lambdaj-new-trends-in-java.html
I am an happy Scala developer too. But sometimes you are just obliged to develop in Java (in my experience, in the real world, about the 80% of times you cannot choose in which language you have to write your code) and in this case some of the lambdaj features could be helpful (or I hope so). I just wanted to bring to Java some functional features that are totally missing. Of course the result is not completely satisfying mainly due to the limitation imposed by Java itself.
As for the internal lambdaj mechanism, yes it uses a ThreadLocal in order to achieve that result. If you have other questions, curiosities or even better suggestions and constructive critics about lambdaj maybe you could be interested to register yourself to the lambdaj mailing list here:
http://groups.google.com/group/lambdaj
Bye
Mario
Well, of is presumably a static method which is imported statically so it can be called without the enclosing class name. I expect that var is the same. Both methods must return some type which have the methods subsequently called:
public class Printable {
public void println(Var var);
}
public class Fac {
public static Printable of(Object o) {
return new Printable(o);
}
public static Var var(Class<?> clazz) {
return new Var(clazz);
}
}
All of a sudden:
Fac.of(System.out).println(Fac.var(String.class));
Is valid Java. Using static imports, hey presto:
import static Fac.*;
of(System.out).println(var(String.class));
The curly-braces are obviously valid Java as you can add these in any method to aid in defining a lexical sope. This API-design style is called fluent and is best showcased by the JMock testing library.
By the way, if this is supposed to introduce closures to Java, it's quite ridiculous - the syntax is unreadably awful. Their I/O example actually made me laugh out loud. Try Scala!
EDIT - the two println calls are associated I believe because the first sequence of calls allow the library to capture the variables which you have passed in as parameters. These are probably captured in some ThreadLocal structure. When you then call a (also presumably static) println method, the library is using this captured data to actually execute the behaviour at a later point. Also testing related, the EasyMock test framework uses a similar mechanism (which uses Java proxies in the background) to capture expected values.