Java: Iterate through Nested Classes - java

Currently, I have a number of nested classes inside an outer class. Each nested class has an overriden toString method. My goal is to iterate through these nested classes to access the value returned by the overriden toString without initializing every single nested class. I've tried iterating through the array returned by Class#getDeclaredClasses
The simplified outer class:
class MyClass {
static class NestedClassOne {
#Override
public String toString() {return "One";}
}
static class NestedClassTwo {
#Override
public String toString() {return "Two";}
}
}
The method I've tried, using the Class#getDeclaredClasses array:
for (Class<?> NestedClass : MyClass.class.getDeclaredClasses()) {
System.out.println(NestedClass.toString());
}
This method, to my dismay, only prints the following:
class ... MyClass$NestedClassTwo
class ... MyClass$NestedClassOne

Your toString() is invoked directly on the class object. I.e., it calls Class<T>.toString() not NestedClassOne.toString(). For that you need to use reflection:
Class<NestedClassOne> clazz = NestedClassOne.class;
Method method = clazz.getMethod( "toString" );
NestedClassOne obj = clazz.newInstance();
Object result = method.invoke( obj );
System.out.println( result );
I'll repeat my comments however:
This sounds like a bad idea. You really shouldn't be using reflection like this. An enum or something similar would likely be a better fit.
It's just kind of obviously super brittle. It throws numerous exceptions, which enums won't. If the code structure changes at all (changing to a different constructor for example) it breaks. If the method name changes, the compiler can't detect it. Etc. I wouldn't want to maintain code that works the way you are asking for.

My goal is to 1) iterate through these nested classes to 2) access the value returned by the overridden toString without initializing every single nested class.
The first part you are doing. The second part is not possible.
The toString() methods you are trying to call are instance methods.
You can't call an instance method until you have created an instance.
You can't create an instance of a class without triggering1 the static initialization of the class.
What your attempted code is actually doing is calling the toString() method on the Class objects. That gives you the names of the classes.
#markspace's answer shows how to create an instance and call the toString() method via reflection. The caveats are that it assumes that each class has a no-args constructor, and that creating the instances doesn't have undesirable side-effects.
1 - There are scenarios involving classes with cyclic dependencies where an instance of a class may be created before its static initialization has completed.
I agree with #markspace's comments. I'm not sure what the real purpose of this is, but there is likely to be a better (more robust) way than calling toString() methods. (For example ... using a custom annotation with runtime retention.)
Even if there isn't, the constraint of not initializing the classes seems artificial to me: is this a premature optimization?

Related

Getting class method name

class className {
void method1(void){
*do something
}
}
Is there any way to get the name of the class method above, and/or perhaps a pointer? I wanted to make a GUI object generated by my methodGenerator class to be displayed depending on the className and its class methods mentioned. I am learning Java at the moment.
For example, if className1 has method1, and method2; and className2 has only method1.
In Java, you can use reflection to get method names. There are several ways of doing this, for example, if you want all the methods of the class, you can do something like this:
Method[] methods = ClassName.class.getMethods(); // Gives you all the methods
You can invoke the method by calling invoke() on the instance of Method. If the method is private, you will have to make it accessible by calling setAccessiable(true) on the Method and then calling invoke() on the instance of that Method

Java strange syntax - (Anonymous sub-class)

I have come across below strange syntax, I have never seen such snippet, it is not necessity but curious to understand it
new Object() {
void hi(String in) {
System.out.println(in);
}
}.hi("strange");
Above code gives output as strange
thanks
You've created an anonymous sub-class of Object, which introduces a method, called hi, after which you invoke this method with parameter "strange".
Let's suppose you had:
class NamedClass extends Object {
void hi(String in) { System.out.println(in); }
}
NamedClass instance = new NamedClass();
instance.hi("strange");
If this class was needed at exactly one place, there's no real need of being named and so on - by making it an anonymous class, you get rid of its name, the class gets defined and instantiated and the hi method invoked immediately within a single expression.
You've created an annonymous sub-class of Object and then invoke the method.
Four types of anonymous inner class exists :-
1)Inner class,
2)Static nested classes
3)Method local inner classes
4)Anonymous inner classes
In Annonymous inner classes,you can define,instantiate and use that inner object then and there
This is perfectly normal and is Called an anonymous class it is used very often where if u want to pass an object reference to a function you will do it with anonymous classes or for the use of callbacks, now .hi at the end is valid because you just used the new operator to instantiate an object of type Object and you have a reference to it so that's why it works.

How do I call a base class's own method from another method when it's overridden?

public class Parent{
private Object oBase;
public Object getObject(){
// [some logic]
return oBase;
}
public String getObjectValue(){
return getObject().getValue();
}
public class Child extends Parent {
private Object oChild;
public Object getObject(){
return oChild;
}
public Object getObjectValue(){
return getObject().getValue();
}
public String getParentObjectValue(){
return super.getObjectValue();
}
}
In the above template, I need a way to make sure that the getObject() in Parent.getObjectValue() calls Parent.getObject() and not Child.getObject(), so that the child class can have getters to oBase and oChild.
I've tried using ((Parent)this).getObject().getValue() in Parent.getObjectValue(), but it still polymorphs to the child definition. Is there way to force static binding in java for a specific call?
I'm trying to avoid duplicating the [some logic] from Parent.getObject() in Parent.getObjectValue(), but I guess I'll have to if there's really no way around it.
You can either make the getObject() method private, or change the method name so that polymorphism will not kick on. Overall, you'll have to rethink your design.
Other options are to extract the [some logic] to a third method and invoke this from both getObject() and getObjectValue(). Please keep in mind the Command Query separation principle when you use this design.
You could just refer to the private field 'oBase' directly, instead of using the 'getObject()' method.
You can't force a call to the Parent's method from outside the child class, due to polymorphism. Indeed, for a Child object, the parent method does not exist anymore, because it has been overriden.
You don't seem to need any aspect of polymorphism here (though it's hard to tell without more information). If, indeed, you do not need it (different use cases), then change your methods' names so that it does not happen.
Note: If you're in the child class, then you can use super, but I don't think this is your case.

Java: Alternative to passing "this" as constructor argument in order to reference creating object

I've spent a while thinking about different solutions that the one I went for as I've read around (I am not really experienced with Java yet) that using this for a constructor argument isn't usually a good practice.
What I am trying to do is to instantiate several objects of class JobGroupMod and for every JobGroupMod I have to create a certain number of JobMod objects that must be able to reference back the JobGroupMod objects in which they've been spawned from.
In order to accomplish that I am passing "this" to the JobMod constructor but, even if working, it didn't feel like proper designing.
public class JobGroupMod implements JobGroup {
public JobGroupMod(Node n,Set<Job> clusterJobs){
JobMod j=new JobMod(n,this);
}
}
And now the JobMod class:
public class JobMod implements Job {
public JobMod(Node n, JobGroup jg){
setJobGroup(jg);
}
}
My question is, is there a better way of solving this, or is my solution the suggested way?
You should try using a static factory method (Effective Java link).
This way you avoid passing this in a constructor call, which is highly ill-advised to say the least.
example code:
public class JobGroupMod implements JobGroup {
public static JobGroupMod createModeMod(Node n, Set<Job> clusterJobs) {
JobGroup jg = new JobGroupMod();
JobMod j = new JobMod(n, jg);
return jg;
}
}
As long as it remains the only thing you do in the JobGroupMod constructor is is fairly safe as long as you understand the ramifications. There's a lot of Java code in the real world that does this. It's still not something you really want to do, especially when you start talking about multithreading and concurrency.
The danger is passing this to something else before an object is fully constructed. If the constructor were to throw an exception after you did this and not fully construct, you could have a nasty problem. If another thread were to access the object you passed this to before it was fully constructed, you'd have a nasty problem.
What you'll often find in Java is people using a factory pattern to avoid this, an "init" type method, or dependency injection.
Generally there is no magic. You can either pass parameter via constructor or initalize it later using setter/init method etc.
If your class JobMod needs reference to JobGroupMod and has nothing to do without it pass it using constructor. If sometimes it can stand without it create init() method or setter that can initialize this reference.
BTW sometimes you have to create both parameterized and default constructor: first for regular programmatic usage, second if you are using XML, JSON or other serialization that is going easier for bean-like classes. In this case at least create javadoc that explains that default constructor should not be used directly.

How to store a reference to a class in Java?

Is there any way in Java to store a reference to a class? Here's what I want to do:
public class Foo
{
public static void doSomething() {...}
};
SomeClass obj = Foo;
obj.doSomething();
Is there some class "SomeClass" which lets me store a reference to a class, such that I can later use that stored object to call a static member of the original class?
The obvious thing would be class Class:
Class obj = Foo.class;
obj.someMember().doSomething();
but I haven't figured out which of class Class's members might act as "someMember()"... none of them, I think.
Does anyone know if what I'm trying to do is possible in Java?
You can dynamically get a method from a Class object using the getMethod() methods on the class. If a method is static, then the "object" parameter of "invoke" will be null.
For example, the "obj.someMember()" above would be something like this:
obj.getMethod("someMember", null).invoke(null, null);
The extra nulls are because your method requires no parameters. If your method takes parameters, then they will need to be passed in accordingly.
This will throw various checked exceptions, so you'll need to handle those as well.
Once you've invoked the method, it will return an Object. You'll want to cast that to whatever type you're expecting, and then you'll be able to run the "doSomething()" method directly on that.
This is using a trick called reflection, if you'd like to read up more on it. :)
If you are using jdk1.5 or above, annotation will be a choice when you want to get metadata of Class.

Categories