Assume I am making a class called Government. Government has members like officers, ministers, departments etc. For each of those members I create an interface, and any specific government defines them as they like.
The main method in the Government class is called Serve(Request req). Assume that the query rate is very large (1000+ queries per second).
To create the government, I can:
1) Use Java generics to write Government<Class Minister, Class Officer, ...> and any specific government implementation needs to create its own Government object in java code, and a main() to have deployable jar.
2) Have a configuration file which specifies the class names of officers, ministers etc., and whenever Serve() is called, it uses Class.forName()and Class.newInstance() to create an object of the class. Any new government just needs to write classes for its members, and the configuration file. There is one single main() for all governments.
From a purely performance point of view - which is better and why? My main concerns are:
a) does forName() execute a costly search every time? Assume a very large universe of classes.
b) Do we miss out on the compiler optimizations that might be performed in case 1 but not in case 2 on the dynamic classes?
As long as you reuse your goverment object, there is no difference at runtime. Difference isonly at object creation time.
1 & 2 differ in concept - 1 ist hardwired, while 2 is dynamic ( you may even use DI contrainers like spring, guice or pico - basically you proposed to write your own )
As for forName() performance - it is up on classloader ( and also on container ) . MOst of them would cache name resolution results, look up in map - but I can not speak for all
As for optimisations - there are compiler optimisations, and also agressive runtime optiomisations from JIT compilers - they matter more.
I don't get it. Those two are not alternatives; they are pretty much orthogonal: Generics is a compile-time construct. It is erased and does not translate to anything at runtime. On the other hand, loading classes by calling forName is a runtime thing. One does not affect the other.
If you are using generics, then that means you don't need the class object at runtime, since in generics you don't have access to the class object, unless you pass it in explicitly. If you don't need the class object at runtime, that means you don't need to load it with forName, so that is inconsistent with forName. If you do pass the class object in explicitly, then that means you already have the class object and don't need to load it, also inconsistent with forName.
Your description kind of reads like this to me: "I want to use dependency injection, should I roll my own?"
Look into Spring (or Guice by Google). I'll assume Spring.
Create interfaces for stuff and configure which implementation to use for each in Spring.
Related
Java's Dynamic Proxy Docs describe these constructors as the following:
A dynamic proxy class is a class that implements a list of interfaces specified at runtime such that a method invocation through one of the interfaces on an instance of the class will be encoded and dispatched to another object through a uniform interface. Thus, a dynamic proxy class can be used to create a type-safe proxy object for a list of interfaces without requiring pre-generation of the proxy class.
Now, while everything in this sentence is accurate. All of this information is in fact present at compile time. In Java, when you are creating a proxy, you specify the exact interface you want to proxy in your code.
Now the first thing that really confuses me, is why the byte code here needs to be generated at run time? All of this information is present at the compile time... (and you don't even have to deal with type erasure)
P.S: I am not sure if this is still the case, basing this on a quite dated accepted answer here: How does Java's Dynamic Proxy actually work?)
The next step in getting this work is the type checking/type inference. I am not sure how Java actually handles this, but you need to be able to use Proxy<A> interchangeably with A. In order to pull this of you need the following:
∀ method m ∈ A, m ∈ Proxy<A>
Which means that
you need your proxy to have the same structure
you need some kind of delegation (i.e. dynamic dispatch).
Once you start writing out the inference rules, this gives us something very familiar. Structural Typing
Now Java doesn't have structural typing but one could easily add the few inference rules (i.e. Typescript) especially given Java has boxed primitives (Scala for example doesn't which makes it very difficult to introduce structural inference).
The Actual Question
Reflection is hard, not safe and not super performant. My question is why and how Java's proxies use reflection? It seems like most of this functionality could be implemented using other features already present in the language.
In Head First Design Patterns, it was mentioned that you should code to an interface instead of an implementation however the last part of the code example got me confused. How is assigning the concrete implementation of an object at runtime a better design?
Does it mean that its better to put the instantation of the objects within a method in the class that uses the supertype? (a method whose purpose is specifically returning an object to a variable of the superclass)
//Programming to an implementation would be:
Dog d = new Dog();
d.bark();
//Programming to an interface/supertype would be:
Animal animal = new Dog();
animal.makeSound();
//Even better is assigning the concrete implementation at runtime: (says the book)
a = getAnimal();
animal.makeSound();
Even better way is to get the concrete class figured by someone else depending on the environment/context of your code execution. This is called Inversion of control/ dependency injection where the actual class is either configured in some configuration files or coding by convention is used to identify the correct file.
Coming back to why,imagine a project of moderate complexity where you have to talk to a DB. If you hard code the way to access a DB , you will end up asking customers to stick to a particular type/version of the DB. This is how JDBC works. Similarly for more complex scenarios, imagine moving from Db based system file based. Once you get that software should be designed for flexibility, its easy to appreciate the delayed initialisation of concrete classes.
If I were to say why in one word, then it would be: Centralization.
What I mean by this, is that you assign those concrete types at the start of your application somewhere in a single place and provide them to the classes that need them as interfaces, so those classes don't get coupled to the concrete types themselves but rather rely on those abstractions or interfaces.
This is similar to using the Factory pattern, so you don't spread object creation through out the program but rather in a single spot, which is easy to modify in the future.
This also enables you to use Dependency Injection and Inversion of Control which in turn comes with a bunch of good stuff like better testing, maintainability, run-time configuration, etc .
Some classes in the standard Java API are treated slightly different from other classes. I'm talking about those classes that couldn't be implemented without special support from the compiler and/or JVM.
The ones I come up with right away are:
Object (obviously) as it, among other things doesn't have a super class.
String as the language has special support for the + operator.
Thread since it has this magical start() method despite the fact that there is no bytecode instruction that "forks" the execution.
I suppose all classes like these are in one way or another mentioned in the JLS. Correct me if I'm wrong.
Anyway, what other such classes exist? Is there any complete list of "glorified classes" in the Java language?
There are a lot of different answers, so I thought it would be useful to collect them all (and add some):
Classes
AutoBoxing classes - the compiler only allows for specific classes
Class - has its own literals (int.class for instance). I would also add its generic typing without creating new instances.
String - with it's overloaded +-operator and the support of literals
Enum - the only class that can be used in a switch statement (soon a privilege to be given to String as well). It does other things as well (automatic static method creation, serialization handling, etc.), but those could theoretically be accomplished with code - it is just a lot of boilerplate, and some of the constraints could not be enforced in subclasses (e.g. the special subclassing rules) but what you could never accomplish without the priviledged status of an enum is include it in a switch statement.
Object - the root of all objects (and I would add its clone and finalize methods are not something you could implement)
References: WeakReference, SoftReference, PhantomReference
Thread - the language doesn't give you a specific instruction to start a thread, rather it magically applies it to the start() method.
Throwable - the root of all classes that can work with throw, throws and catch, as well as the compiler understanding of Exception vs. RuntimeException and Error.
NullPointerException and other exceptions such as ArrayIndexOutOfBounds which can be thrown by other bytecode instructions than athrow.
Interfaces
Iterable - the only interface that can be used in an enhanced for loop
Honorable mentions goes to:
java.lang.reflect.Array - creating a new array as defined by a Class object would not be possible.
Annotations They are a special language feature that behaves like an interface at runtime. You certainly couldn't define another Annotation interface, just like you can't define a replacement for Object. However, you could implement all of their functionality and just have another way to retrieve them (and a whole bunch of boilerplate) rather than reflection. In fact, there were many XML based and javadoc tag based implementations before annotations were introduced.
ClassLoader - it certainly has a privileged relationship with the JVM as there is no language way to load a class, although there is a bytecode way, so it is like Array in that way. It also has the special privilege of being called back by the JVM, although that is an implementation detail.
Serializable - you could implement the functionality via reflection, but it has its own privileged keyword and you would spend a lot of time getting intimate with the SecurityManager in some scenarios.
Note: I left out of the list things that provide JNI (such as IO) because you could always implement your own JNI call if you were so inclined. However, native calls that interact with the JVM in privileged ways are different.
Arrays are debatable - they inherit Object, have an understood hierarchy (Object[] is a supertype of String[]), but they are a language feature, not a defined class on its own.
Class, of course. It has its own literals (a distinction it shares with String, BTW) and is the starting point of all that reflection magic.
sun.misc.unsafe is the mother of all dirty, spirit-of-the-language-breaking hacks.
Enum. You're not allowed to subclass it, but the compiler can.
Many things under java.util.concurrent can be implemented without JVM support, but they would be a lot less efficient.
All of the Number classes have a little bit of magic in the form of Autoboxing.
Since the important classes were mentioned, I'll mention some interfaces:
The Iterable interface (since 1.5) - it allows an object to participate in a foreach loop:
Iterable<Foo> iterable = ...;
for (Foo foo : iterable) {
}
The Serializable interface has a very special meaning, different from a standard interface. You can define methods that will be taken into account even though they are not defined in the interface (like readResolve()). The transient keyword is the language element that affects the behaviour of Serializable implementors.
Throwable, RuntimeException, Error
AssertionError
References WeakReference, SoftReference, PhantomReference
Enum
Annotation
Java array as in int[].class
java.lang.ClassLoader, though the actual dirty work is done by some unmentioned subclass (see 12.2.1 The Loading Process).
Not sure about this. But I cannot think of a way to manually implement IO objects.
There is some magic in the System class.
System.arraycopy is a hook into native code
public static native void arraycopy(Object array1, int start1,
Object array2, int start2, int length);
but...
/**
* Private version of the arraycopy method used by the jit
* for reference arraycopies
*/
private static void arraycopy(Object[] A1, int offset1,
Object[] A2, int offset2, int length) {
...
}
Well since the special handling of assert has been mentioned. Here are some more Exception types which have special treatment by the jvm:
NullPointerException
ArithmeticException.
StackOverflowException
All kinds of OutOfMemoryErrors
...
The exceptions are not special, but the jvm uses them in special cases, so you can't implement them yourself without writing your own jvm. I'm sure that there are more special exceptions around.
Most of those classes isn't really implemented with 'special' help from the compiler or JVM. Object does register some natives which poke around the internal JVM structures, but you can do that for your own classes as well. (I admit this is subject to semantics, "calls a native defined in the JVM" can be considered as special JVM support.)
What /is/ special is the behaviour of the 'new', and 'throw' instructions in how they initialise these internal structures.
Annotations and numbers are pretty much all-out freaky though.
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.
Suppose, I have a lot of classes, which are constructed using Java reflection (for some reason). Now I need to post-inject values to fields, which are
annotated with #PostInject.
public class SomeClass {
#PostInject
private final String someString = null;
public void someMethod() {
// here, someString has a value.
}
}
My question is: what is a fast way to set a field using reflection?
Remember, I need to do this very often on a lot of classes, that's
why performance is relevant.
What I would do by intuition is shown by this pseudo-code:
get all fields of the class
clazz.getFields();
check, which are annotated with #PostInject
eachField.getAnnotation(PostInject.class);
make these fields accessible
eachAnnotatedField.setAccessible(true);
set them to a certain value
eachAnnotatedField.set(clazz, someValue);
I'm afraid that getting all fields is the slowest thing to do.
Can I someone get a field, when I know it from the beginning?
NOTE: I can't just let the classes implement some interface, which would
allow to set the fields using a method. I need POJOs.
NOTE2: Why I want post-field injection: From the point of view of an API user, it must be possible to use final fields. Furthermore, when the types and number of fields are not known by the API a priori, it is impossible to achieve field initialization using an interface.
NOTE2b: From the point of view of the user, the final contract is not broken. It stays final. First, a field gets initialized, then it can't be changed. By the way: there are a lot of APIs which use this concept, one of them is JAXB (part of the JDK).
How about doing steps 1 to 3 just after you constructed the object and saving the set of annotated fields that you obtain either in the object itself or by keeping a separate map of class to set-of-annotated-fields?
Then, when you need to update the injected fields in an object, retrieve the set from either the object or the seperate map and perform step 4.
Don't know if it's any good, but this project looks like it would do what you want. Quote:
A set of reflection utilities and
miscellaneous utilities related to
working with classes and their fields
with no dependencies which is
compatible with java 1.5 and generics.
The utilities cache reflection data
for high performance operation but
uses weak/soft caching to avoid
holding open ClassLoaders and causing
the caches to exist in memory
permanently. The ability to override
the caching mechanism with your own is
supported.
Another option, as you say you know the few fields concerned from the beginning, is to ask only for those fields or methods.
Example : see getDeclaredMethod or getDeclaredField in java/lang/Class.html
You can exploit existing frameworks that allow to inject dependencies on object construction. For example Spring allows to do that with aspectj weaving. The general idea is that you define bean dependencies at spring level and just mark target classes in order to advise their object creation. Actual dependency resolution logic is injected directly to the class byte-code (it's possible to use either compile- or load-time weaving).
Fastest way to do anything with reflection is to cache the actual Reflection API classes whenever possible. For example I very recently made a yet-another-dynamic-POJO-manipulator which I believe is one of those things everyone ends up doing at some point which enables me to do this:
Object o = ...
BeanPropertyController c = BeanPropertyController.of(o);
for (String propertyName : c.getPropertyNames()) {
if (c.access(propertyName) == null &&
c.typeOf(propertyName).equals(String.class)) {
c.mutate(propertyName, "");
}
}
The way it works is that it basically has that one controller object which lazyloads all the properties of the bean (note: some magic involved) and then reuses them as long as the actual controller object is alive. All I can say is that by just saving the Method objects themselves I managed to turn that thing into a damn fast thing and I'm quite proud of it and even considering releasing it assuming I can manage to sort out copyrights etc.