Uninstantiated Anonymous Classes in Java - java

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).

Related

Method accepting a class as its parameter

I have a class FTSFor rather I should say java enum which implements MEnum interface and SF interface as follows :
public enum FTSF implements MEnum<FTSF>, SF {
private static final Map<String, FTSF> cmap = MEnum.bCMap(FTSF.class);
.........
so on and so forth
Questions :
1) Since FTSF is a Java enum, that's why it can implement as many classes it want? I am slightly confused since implement keyword is usually used when a class implements an interface.
2) I know that one can pass class as an argument inside a method parameter,so above, when FTSF class is passed inside the bCMap method,i am trying to figure out what does gets passed as an argument inside bCMap method. Is it the class file that gets generated when we compile Java code?
1) Enums, just like any other class, can implement as many interfaces as you like. (I got a bit confused as you asked "why it can implement as many classes as it wants". A class can only implement interfaces, not classes. It can extend only one class. As you clarified in a later comment, both MEnum and SF are interfaces.)
2) When you compile a Java class, called T, the Java compiler creates a single object which is an instance of a generic class Class<T>. This is a special class which holds information about the class you've just written - such as its name, and the set of fields and methods it contains. It's part of a feature called Reflection. In this statement from your question:
private static final Map<String, FTSF> cmap = MEnum.bCMap(FTSF.class);
the expression FTSF.class is a reference to this single instance of class Class<FTSF>. So the method bCMap() is being passed a reference to this object; however, given the context, the most likely reason for passing this argument to the method is not because the method wants to know about the class, but because the class object is being used as a dummy argument to tell the compiler that the generic method bcMap returns a Map<String, FTSF> (instead of, for example, a Map<String, Object>).
1) Java classes can only extend one class, but they can implement as many as they want. It doesnt have to do with FTSF being an enum.
2) It is the Class object that represents the FTFS. You can also get it by calling getClass() as long as you arent in a subclass. It is useful for things like reflection. The documentation for it is here https://docs.oracle.com/javase/7/docs/api/java/lang/Class.html

Is it possible to serialize anonymous class without outer class?

I made a small research on web and reviewed related topics on this site, but the answers were contradictory: some people said it is not possible, others said it is possible, but dangerous.
The goal is to pass an object of the anonymous class as a parameter of the RMI method. Due to RMI requirements, this class must be serializable. Here's no problem, it is easy to make class Serializable.
But we know that instances of inner classes hold a reference to an outer class (and anonymous classes are inner classes). Because of this, when we serialize instance of inner class, instance of outer class is serialized as well as a field. Here's the place where problems come: outer class is not serializable, and what's more important - I do not want to serialize it. What I want to do is just to send instance of the anonymous class.
Easy example - this is an RMI service with a method that accepts Runnable:
public interface RPCService {
Object call(SerializableRunnable runnable);
}
And here is how I'd like to call the method
void call() {
myRpcService.call(new SerializableRunnable() {
#Override
public Object run {
System.out.println("It worked!");
}
}
}
As you can see, what I want to do is to send an "action" to the other side - system A describes the code, that should be run on system B. It is like sending a script in Java.
I can easily see some dangerous consequences, if this was possible: for example if we access a field or captured final variable of outer class from Runnable - we'll get into a trouble, because caller instance is not present. On the other hand, if I use safe code in my Runnable (compiler can check it), then I don't see reasons to forbid this action.
So if someone knows, how writeObject() and readObject() methods should be properly overriden in anonymous class OR how to make reference to outer class transient OR explain why it is impossible in java, it will be very helpful.
UPD
Yet another important thing to consider: outer class is not present in the environment that will execute the method (system B), that's why information about it should be fully excluded to avoid NoClassDefFoundError.
You could try making Caller.call() a static method.
However, the anonymous class would still need to be available in the context in which you deserialize the serialized instance. That is unavoidable.
(It is hard to imagine a situation where the anonymous class would be available but the enclosing class isn't.)
So, if someone can show, how I can properly override writeObject and readObject methods in my anonymous class ...
If you make Caller.call() static, then you would do this just like you would if it was a named class, I think. (I'm sure you can find examples of that for yourself.)
Indeed, (modulo the anonymous class availability issue) it works. Here, the static main method substitutes for a static Classer.call() method. The program compiles and runs, showing that an anonymous class declared in a static method can be serialized and deserialized.
import java.io.*;
public class Bar {
private interface Foo extends Runnable, Serializable {}
public static void main (String[] args)
throws InterruptedException, IOException, ClassNotFoundException {
Runnable foo = new Foo() {
#Override
public void run() {
System.out.println("Lala");
}
};
Thread t = new Thread(foo);
t.start();
t.join();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(foo);
oos.close();
Foo foofoo = (Foo) new ObjectInputStream(
new ByteArrayInputStream(baos.toByteArray())).readObject();
t = new Thread(foofoo);
t.start();
t.join();
}
}
Another important thing to remember about: the Caller class is not present in the environment, that executes the method, so I'd like to exclude all information about it during serialization to avoid NoClassDefFoundError.
There is no way to avoid that. The reason that deserialization in the remote JVM is complaining is that the class descriptor includes a reference to the outer class. The deserializing side needs to resolve that reference even if you managed to clobber the reference, and even if you never explicitly or implicitly used the synthetic variable in the deserialized object.
The problem is that the remote JVM's classloader needs to know the type of the outer class when it loads the classfile for the inner class. It is needed for verification. It is needed for reflection. It is needed by the garbage collector.
There is no workaround.
(I'm not sure if this also applies to a static inner class ... but I suspect that it does.)
Attempting to serialize anonymous Runnable instance without outer class refers not only to a serialization problem, but to a possibility of arbitrary code execution in another environment. It would be nice to see a JLS reference, describing this question.
There is no JLS reference for this. Serialization and classloaders are not specified in the JLS. (Class initialization is ... but that is a different issue.)
It is possible to run arbitrary code on a remote system via RMI. However you need to implement RMI dynamic class loading to achieve this. Here is a reference:
http://www.cis.upenn.edu/~bcpierce/courses/629/jdkdocs/guide/rmi/spec/rmi-arch.doc.html#280
Note that adding dynamic class loading for remote classes to RMI introduces significant security issues. And you have to consider issues like classloader leaks.
If you mad enough to do the trick you can use reflection to find field that contains reference to outer class and set it to null.
Your example as stated above cannot work in Java because the anonymous inner class is declared within class Caller, and you explicitly stated that class Caller in not available on the RPC server (if I understood that correctly). Note that with Java RPC, only data is sent over the network, the classes must already be available on the client and the server. It that respect your example doesn't make sense because it looks like you want to send code instead of data. Typically you would have your serializable classes in a JAR that is available to the server and the client, and each serializable class should have a unique serialVersionUID.
You can't do exactly what you want, which is to serialize an anonymous inner class, without also making its enclosing instance serializable and serializing it too. The same applies to local classes. These unavoidably have hidden fields referencing their enclosing instances, so serializing an instance will also attempt to serialize their enclosing instances.
There are a couple different approaches you can try.
If you're using Java 8, you can use a lambda expression instead of an anonymous inner class. A serializable lambda expression does not (necessarily) have a reference to its enclosing instance. You just need to make sure that your lambda expression doesn't reference this explicitly or implicitly, such as by using fields or instance methods of the enclosing class. The code for this would look like this:
public class Caller {
void call() {
getRpcService().call(() -> {
System.out.println("It worked!");
return null;
});
}
(The return null is there because RPCService.Runnable.run() is declared to return Object.)
Also note that any values captured by this lambda (e.g., local variables, or static fields of the enclosing class) must also be serializable.
If you're not using Java 8, your next best alternative is to use a static, nested class.
public class Caller {
static class StaticNested implements RPCService.Runnable {
#Override
public Object run() {
System.out.println("StaticNested worked!");
return null;
}
}
void call() {
getRpcService().call(new StaticNested());
}
}
The main difference here is that this lacks the ability to capture instance fields of Caller or local variables from the call() method. If necessary, these could be passed as constructor arguments. Of course, everything passed this way must be serializable.
A variation on this, if you really want to use an anonymous class, is to instantiate it in a static context. (See JLS 15.9.2.) In this case the anonymous class won't have an enclosing instance. The code would look like this:
public class Caller {
static RPCService.Runnable staticAnonymous = new RPCService.Runnable() {
#Override
public Object run() {
System.out.println("staticAnonymous worked!");
return null;
}
};
void call() {
getRpcService().call(staticAnonymous);
}
}
This hardly buys you anything vs. a static nested class, though. You still have to name the field it's stored in, and you still can't capture anything, and you can't even pass values to the constructor. But it does satisfy your the letter of your initial question, which is how to serialize an instance of an anonymous class without serializing an enclosing instance.
The answer is no. You cannot do that since Inner class will need outer class to be serialized. Also you would run into troubles when you'd try to call the instance method of the outer class within the inner class. Why don't you just have another top level class which you could send?
I'd like to add to this topic. There is a way to achieve what you want, but will require reflection.
Here is a good tutorial on implementing a custom serializable object using writeObject and readObject
And here is a good tutorial (website font is kind of an eyesore, but the content is worth it) on on how Reflection is used to for serialization. The tutorial refers to final fields, but applies to any field.
You'll have to use Reflections getDeclaredField

possible to Java override functions at an instance level?

I'm reviewing some Java code written long ago and not being a Java developer, I have a question. I found the following lines in the body of a class. Someone is creating an instance of SearchQueryParameter however there are curly braces following "new SearchQueryParameter" and it appears that someone overrode some functions here.
My questions are the following.
1) Are these functions overwritten at an instance level?
2) Does this language feature have a name?
public static final SearchQueryParameter X_POSTDOC_WORKFLOW_STEP = new SearchQueryParameter(128,"XPOSTDOCWorkflowStep",AdvancedFields.X_EVENT_POSTDOC_WFSTEP,SearchTypes.XEVENT_DOCUMENTS) {
#Override
protected int getFilterType() {
return SEARCH_FILTER;
}
<<snip>>
};
Thanks, mj
Background:
This is called anonymous class. It is a class that extends a non final class or implements a single interface and you're creating a single instance of this class.
Now, to your questions:
1) Are these functions overwritten at an instance level?
No, they are at level class. You have a new subclass of the desired class and this subclass overrides the method. Then, you create a new instance of the subclass.
2) Does this language feature have a name?
Yes, it is anonymous class.
You probably should have done some research on your own first, but that is called an anonymous inner class.
The code creates an instance of an anonymous class (SearchQueryParameter) and then overrides one method in it.
Essentially, it creates something that extends the SearchQueryParameter class and which overrides the getFilterType() method.
Since only one instance of this particular class definition can ever be created (without reflection), the function may appear like it's being overridden at an instance level but is actually getting overridden at the class level (since it may replace the existing definition).
It's called an anonymous class.

new Object { } Construct

In Java, the standard way to create an object is using
MyClass name = new MyClass();
I also often see the construct
new MyClass() { /*stuff goes in here*/ };
I've been looking online for a while and can't find a good explanation of what the second construct style does or how it does it.
Can someone please explain how and why you would use the second construct?
This construct makes actually two things: 1) It declares an anonymous class which extends the class you use in the constructor and 2) creates an instance of this anonymous class.
Edit: When using such a construct you can observe the anonymous class by looking at the generated .class files. There is the normal MyClass.class file and another one for each anonymous subclass: MyClass$1.class for the first and so on.
You would use the second construct in the case that you want to make an anonymous class. if you have a method that takes a callback as an argument, you might want to specify the implementation of the callback inline as opposed to giving it a name and putting it in a separate file or declaring it elsewhere in the same file.
There's also a trick called double brace initialization where you can get around not having syntax for literal maps and lists by using anonymous classes, like this:
Map map = new HashMap() {{put("foo", 1); put("bar", 2);}};
Here the nested braces create an instance initializer. The object bound to map is not a HashMap, its class is an anonymous class extending HashMap. (That means if you have a PMD rule about classes needing to declare serial uids then it will complain about this.)
Double-brace initialization is a fun trick to know but don't use it in real code. It's not safe to pass around the map created like this, because the inner object keeps a reference to the outer instance so if anything in the program holds onto a reference to the map it keeps the outer object from getting garbage-collected. There are also problems with serialization.
As others have already said, it creates an instance of an anonymous class, subclassing Class. Here's an example how it is commonly used:
panel.addMouseListener(
new MouseAdapter () {
#Override
public void mouseEntered(MouseEvent e) {
System.out.println(e.toString());
}
}
);
The above code creates an instance of an anonymous class which extends MouseAdapter. In the anonymous class the method mouseEntered has been overridden to demonstrate that the anonymous class works basically as any other class. This is very convenient and common way to create (usually simple) listeners.
Second construction creates an instance of anonymous class which is a subclass of Class.
If you want to new a object by a protect constructor from another package, you can use:
new Foo() {};
otherwise you will get an access error. It equals anonymous subclass inherited from Foo class.
From jdk8 onwards you may have seen different syntax seems like creating an objects while using lambda expressions.
NOTE: Lambda expressions don't get translated into anonymous inner classes, they use invoke dynamic that was introduced in Java 7 to execute functional methods.
For Example:
public class LambdaSample {
public static void main(String[] args) {
//If implementation is only one statement then {} braces are optional
Runnable oneLineImplRunnable = ()->System.out.println("This is one line lambda expression");
//Multiple statements in the implementation then {} braces are mandatory
Comparator<StudentTest> stdComparator = (StudentTest s1,StudentTest s2)->{
if(s1.getFirstName().equals(s2.getFirstName())) {
return s1.getLastName().compareTo(s2.getLastName());
}else {
return s1.getFirstName().compareTo(s2.getFirstName());
}
};
}
}

Java member object inside class of same type

I am looking at a codebase and I often see something like:
public class SomeClass
{
protected static SomeClass myObject;
//...
public static SomeClass getObject()
{
return myOjbect
}
}
I'd like to make sure I understand the purpose behind this. Is it to ensure one instance of the class gets shared even if it is instantiated multiple times? I am not sure about the vocabulary here, or else I'd search for the answer, so if this pattern has a name, please let me know.
Also, this seems a little chicken-and-egg definition because the class includes an object of the type of the class. Why isn't this actually paradoxical?
Thanks!
This is really only common with the Singleton Pattern where there is only this one instance of the class. While it has its uses, Singleton is over- and misused more often than not (usually to disguise procedural programming as OO). It also occurs very often in example code for Java AWT or Swing, where you typically subclass Frame / JFrame, and create an instance in a main method inside the same class.
Also, this seems a little
chicken-and-egg definition because the
class includes an object of the type
of the class. Why isn't this actually
paradoxical?
Why do you think it is? The class mainly describes what members instances of this type have - but a static member does not belong to an instance, it belongs to the class itself, so it doesn't have anything to do with the "blueprint" role of the class. Static members are really somewhat un-OO because of that.
But even on the instance level you can have references of the same type. For example, an entry in a linked list would typically have two references to the next and previous entries, which are of the same class.
This is called the Singleton design pattern.
You are correct in stating that the purpose is to ensure only one instance of the class gets created.
Wikipedia has a preyty good article on the pattern.
The pattern you mentioned is called "Singleton", but from your code sample it is not clear if this is really what is intended. Due to the fact that the member is protected, I would guess not - if there are subclasses, then there would probably not be a single instance.
It's called Singleton. You ensure the creation of just ONE (1) object of a given class.
You should add a private Constructor, so the only one who create the object is the class.
public class SomeClass
{
// Using private constructor
protected static SomeClass myObject = new SomeClass();
private SomeClass(){
//...
}
public static SomeClass getObject()
{
return myOjbect
}
}
Much much more here, in Wikipedia
You may want to take a look to Factory Pattern
It's not all that uncommon; it can be a good way to implement the Singleton pattern. There can be other uses as well - sometimes you will want a handful - and no more - of objects of a given class; that class is a good place to hang onto them. In the event that you don't want other classes to be able to create objects of this class, it is common to give the class a private constructor as well.
It's not paradoxical, because the compiler can be aware of a reference to the class before it has fully compiled the class. Later - if you like to think of it this way - it can "fill in the blanks".

Categories

Resources