Given the following three classes how can I use reflection to call the initialize function for the parent class(es) and then the subclass:
public class Test {
public static void main(String[] args) {
ExtendedElement ee = new ExtendedElement();
initialize(ee);
}
public static void initialize(Element element) {
System.out.println(element.getClass());
initialize(element.getClass());
}
public static void initialize(Class clazz) {
System.out.println(clazz.getClass());
}
}
public class Element {
protected String value;
public String getValue() { return value; }
public void setValue(String value) { this.value = value; }
}
public class ExtendedElement extends Element {
protected String extendedValue;
public void setExtendedValue(String extendedValue) {
this.extendedValue = extendedValue;
}
public String getExtendedValue() { return extendedValue; }
}
I'm not quite sure on how to paramertize the initialize function in the Test class, as the clazz parameter is a raw type.
What I essentially need is to call initialize up the class hierarchy if what I pass into initialize is of a subclass of Element.
Something like the following:
public void initialize(Class clazz) {
if (Element.class.isInstance(clazz.getClass().getSuperclass()) {
initialize(clazz.getClass().getSuperclass());
}
//Work to call initialize function
}
Edit 1:
Can't I parameterize the above pseudo function differently to retain the type of the object and then call the function I need to?
What I'm trying to do is avoid having to have the same method overridden for each of my classes and allow some inheritance for my Selenium 2 Page Objects. What I need to do is be able to is introspect the superclass(es) of my self and initialize each of my WebElement fields prior to running tests on these fields.
These are being injected with spring, and to further complicate things I am allowing tests to be written using Spring Expression language. I am lazy loading my beans, and using the InitializingBean interface to attempt to initialize my WebElements prior to their usage to avoid NPEs.
I had to wrap the WebElements with a custom object so that I could inject the location strategies using spring (We reuse a lot of pieces, but they have different ids / class names dependent upon where they are used in the application; this was done prior to me getting here and will not be changed at this time despite my arguments for consistency). For example we have a date widget that has different granularities, sometimes we need just a month, sometimes month and year, etc... It'd be nice if I could use an abstract class and break these commonalities down to their least common denominator and extend from there. To do that I need to be able to do the following in my base class:
public abstract class PageObject implements InitializingBean {
...
public void afterPropertiesSet() {
//Pass in concrete impl we are working with - this allows me to initialize properly
initializeWebElements(this.getClass());
}
...
public void initializeWebElements(Class clazz) {
//This does not grab inherited fields, which also need to be initialized
for (Field field : clazz.getDeclaredFields()) {
if (WidgetElement.class == field.getType()) {
Method getWidgetElement = clazz.getDeclaredMethod("get" +
StringUtils.capitalize(field.getName()), new Class [] {});
WidgetElement element =
(WidgetElement) getWidgetElement.invoke(this, new Object [] {});
element.initElement();
}
}
You can't call a method at a specific level. The only thing is you have access to the super keyword inside the class itself.
To make this work, you want to call super.initialize() from within each subclass, then just call it via reflection.
This is not C++, where you can call a specific method at a specific level of the inheritance hierarchy.
I'm not quite sure on how to parameterize the initialize function in the Test class, as the clazz parameter is a raw type.
Nothing in your example requires you to make use of the generic type parameter, so declare it as Class<?>.
I don't understand what your initialize methods are really trying to do, but there are a number of problems:
You seem to have one initialize method that takes an instance (of Element) as an argument, and another that takes a Class object as an argument. That's really apples and oranges stuff ... and you need to explain what you are trying to do.
Your attempt at fleshing out the method contains this:
Element.class.isInstance(clazz.getClass().getSuperclass())
This will never evaluate to true, because it is asking if some Class object is an instance of the Element class. (What is more, clazz.getClass().getSuperclass() is actually going to be the same as java.lang.Object.class. The class of a Class object is java.lang.Class and its superclass is java.lang.Object).
But I can't figure out what it should be, because you don't clearly describe what you are trying to achieve.
Here is my temporary solution, leaving question open to hopefully gather some better answers though for my use case.
public abstract class PageObject implements InitializingBean {
...
public void afterPropertiesSet() {
Class clazz = this.getClass();
do {
initializeElements(clazz);
clazz = clazz.getSuperclass();
} while (clazz != null);
}
Related
This seems like a newbish question, but the last time I worked with Java, the language didn't have generics. I have a class hierarchy (names changed to be as generalized as possible):
public abstract class AbstractBase { .... }
public class ConcreateSubA extends AbstractBase { .... }
public class ConcreateSubB extends AbstractBase { .... }
...
public class ConcreateSubZZ9PluralZAlpha extends AbstractBase { .... }
...
I'm trying to clean up some legacy code, and there's one place where a ton of repetitive duplication can all be factored out into a single routine via generics. (I'm thinking generics because when this routine is called, it needs to operate on only one of the concrete classes.)
The routine looks like
public <Thing extends AbstractBase> void someFunc()
{
another_function_call (Thing.concreteSpecialToken);
// could also be
// another_function_call (Thing.concreteSpecialToken());
// if methods are more feasible than fields
// Cannot use
// another_function_call (Thing().concreteSpecialToken());
// because creating instances of these types is a Major Operation[tm]
}
I'm leaving out about a zillion lines, but that's the important part: someFunc() is type parametric (it actually takes arguments but none of them are Things so no inference). Eventually I need to fetch a special token and this is where I'm getting fuzzy.
The tokens are huge-ass unique strings for each concrete class. They're class-based, not instance-based. The actual token value is declared as a private static final field in each subclass.
So I need to use the public methods/fields of a base class to (eventually) get to the private static field of a subclass. Obviously I can't declare an abstract static method in the base, because that makes no sense. If the data were instance-based, then this would be trivial, with a polymorphic getter in the base class, but the subclass stuff is static.
I feel like I'm missing a feature of Java generics here, but I can't use Thing.whatever() unless the whatever is something that's possible to declare in the abstract base class. I'm running up against either limitations of Java or my lack of expertise trying to bridge the gap. The one attempt I made that seemed promising also had a ton of code duplication all the way down the class hierarchy, defining abstract methods with the exact same code over and over... which is what generics are supposed to help prevent!
I'm running up against either limitations of Java or my lack of expertise trying to bridge the gap.
It's a limitation of Java, although a fairly reasonable one IMO. Basically you're still trying to use static members as if they were polymorphic, and that's not going to work - generics don't help you there.
Options:
Use reflection... but bear in mind that type erasure means you can't get at the Class for Thing unless you pass it in explicitly
If you've got an instance of Thing anyway, just make it an abstract instance member, which in each implementation happens to return the value of a static field
Create a separate type hierarchy which will use instance members
If I understand it correctly, you need the concrete class of the type parameter. The usual way of doing it is to declare your method like this: public <T extends AbstractBase> void someFunc(Class<T> clazz)
This of course means an extra parameter needs to be passed to the method and you need to use reflection to access the static fields, but given Java's type erasure it's the only way.
The moral of the story is that generics and statics don't go very well together.
A bit clunky but if someFunc took a Class<Thing> parameter you could use reflection:
public <Thing extends AbstractBase> void someFunc(Class<Thing> clz) {
// exception handling omitted
Object whatever = clz.getDeclaredMethod("whatever").invoke(null);
But you could maybe take better advantage of polymorphism by using nested classes, something like
public abstract class AbstractBase {
public static class Info {
public String getInfo() {
return "AbstractBase";
}
}
}
public class ConcreteSubA extends AbstractBase {
public static final Info INFO = new Info() {
public String getInfo() { return "ConcreteSubA"; }
}
}
and have someFunc take an AbstractBase.Info parameter.
public <Thing extends AbstractBase> someFunc(AbstractBase.Info inf) {
String info = inf.getInfo();
}
// call it as
ConcreteSubB csb = someFunc(ConcreteSubB.INFO);
The idea is that each class in the hierarchy has a singleton instance of Info holding its formerly-static data.
If you want to keep the token as it is, a private static final field, you can get it through reflection:
public <Thing extends AbstractBase> void someFunc(Class<Thing> clz)
{
try {
Field field = clz.getField("concreteSpecialToken");
field.setAccessible(true);
Object concreteSpecialToken = field.get(null);
another_function_call (concreteSpecialToken);
} catch (IllegalAccessException e) {
handle(e);
} catch (NoSuchFieldException e) {
handle(e);
}
}
At call site, you have to do someFunc(ConcreateSubZZ9PluralZAlpha.class). But I wonder if you can do that, why don't you just pass the token object as a parameter, as in someFunc(ConcreateSubZZ9PluralZAlpha.concreteSpecialToken)? Or maybe even move the method someFunc() to the token class itself.
I have a Cube object with a public 'x' field. I have a toString method in my Cube class which prints out the x,y,z fields, but when I directly access it, I get an error where: field cannot be resolved or is not a field.
public <T> void setPosition(T object){
System.out.println(object);
System.out.println(object.x); // error here
}
I would recommend defining an interface that declares the method that your multiple different types will expose. Something like:
public interface ValueProducer {
public String getValue();
}
Then, your Cube type would look like this:
public <T extends ValueProducer> void setPosition (T obj) {
System.out.println(obj);
System.out.println(obj.getValue());
}
Then any type with which you wish to use this method need only implement the interface ValueProducer, and can still extend or implement whatever other types are appropriate for their use cases.
Or, you could omit generics altogether, and just pass obj in as a ValueProducer.
your method does not know what is the type T.
But we can say T is some class which extends
public class GenericCube {
public String value;
}
So, now we able to access the value because we know about it
public <T extends GenericCube> void setPosition(T obj){
System.out.println(obj);
System.out.println(obj.value);
}
I found that I could access the field utilizing Reflection methods and cast to the object I needed. This is supported using an abstract class with this field so that all objects inheriting from this object can utilize this function.
public <T> void setPosition(T object) {
Field xField = object.getClass().getField("x");
Field boxField = object.getClass().getField("boundBox");
float xpos = (float)xField.get(object);
BoundingBox box = (BoundingBox)boxField.get(object);
}
I'm open to critique, but this has been working very well with my multiple classes inheriting from my abstract base class. The reason for this method, is for another class to work with these other classes without creating multiple functions, thus giving flexibility for a user who wants to create their own classes inheriting from the abstract class.
I haven't quite found an elegant way to solve this issue. I have an abstract class that several other classes are inheriting with an abstract method that can contain anywhere from zero to 4-5 arguments of varying types.
public abstract class Item {
public abstract void use();
}
For instance, I have a Book class that inherits this and takes no arguments when overriding use(), I have a Key class that inherits and takes a String and a Queue as arguments when overriding, etc...
I've tried using generics but I have to input the number used, such as Item, when it actually depends on the class.
public abstract class Item<T,U> {
public abstract void use(T arg1, U arg2); //Number of arguments/types could be more or less
}
I've tried sending a variable list of Objects but the object types are always variable and I've unsure as to the syntax to receive in the inheriting classes.
public abstract class Item<T> {
public abstract void use(T... arguments);
}
public class Book extends Item<?> {
public void use(?);
}
public class Book extends Item<String, Queue> { //Wrong number of arguments since I can't use Item<T...>
public void use(String str, Queue q); //fails
}
I may just be doing something wrong - can anyone offer any assistance or insight?
I've struggled with the same question, and there's not a perfect answer, but I can give you a few things to consider. First, you're basically trying to do something that is inherently against Object Oriented Programming, which is that you're trying to create a variable interface. The point of an interface is that code that gets an abstract version of the object (the Item rather than the Book, for example), knows how to invoke the use() method. This means that they must know what can be passed to the use() method. If the answer depends on the implementation of the abstract class or interface, then you need to ensure that the code using it actually knows what kind of implementation (Book, etc.) that it's using, otherwise it's not going to know how to invoke use() with the appropriate parameters anyway. It sounds like you need to refactor your code, in all honesty.
However, there is a way to answer your question as stated without refactoring the architecture. You could create a class that's data is all of the different types of parameters that could possibly be passed to the use() method, have the calling code set the fields of that class, and then pass that to the use() method. For example:
public class UseParameters {
private String string;
private Queue queue;
// Any other potential parameters to use(...)
public void setString(String string) {
this.string = string;
}
public String getString() {
return string;
}
// All of the other accessor methods, etc.
}
Then, you could define the use method in Item like this:
public abstract void use(UseParameters params);
And any code using an Item would have to set the parameters of the object appropriately:
Item item = // However you're going to get the item
UseParameters params = new UseParameters();
params.setString("good string");
params.setQueue(new Queue());
item.use(params);
I just want to point out that if the code above knows the Item is a Book (which is how it knows to set the String and Queue, then why not just get a Book and skip needing an abstract class with a variable use() method altogether? But I digress. Anyway, the Book would then implement the use() method like so:
#Override
public void use(UseParameters params) {
if(params.getString == null || params.getQueue() == null)
// throw exception
// Do what books do with strings and queues
}
I think that gets you what you want, but you should consider refactoring, I think.
What you want is the Value Object Pattern.
Define a class that encapsulates the various parameter types into one value object, and have the abstract method accept a parameter of this type. Each variation of parameters you were considering would have its own value class.
Then simply add a generic type to the class and have the abstract method accept a parameter of that type:
public abstract class Item<V> {
public abstract void use(V v);
}
To use it, suppose MyItem needs a value object of type MyValueClass:
public class MyItem extends Item<MyValueClass> {
public void use(MyValueClass v) {
}
}
If the types to be used as argument are always variable I don't see a reason to use generics. Just use plain Object type:
public abstract class Item {
public abstract void use(Object ... arguments);
}
public class Book extends Item {
public void use(Object ... arguments) { ... }
}
The best approach I can think of is to group the items according to the behavior of their use() method.
Example
public abstract class QueueableItem {
public abstract void use(String, Queue);
}
public abstract class OrdinaryItem{
public abstract void use(String);
}
If the grouped items share a common behavior (common as in same method signature & return value), you can define and extend a parent class that will contain the definition of this common behavior.
Yes, we can provide parameters to abstract method but it is must to provide same type of parameters to the implemented methods we wrote in the derived classes.
I have a superclass, and then several subclasses, like this:
public abstract class A {
public abstract int getValue();
}
public class B extends A {
public int getValue() {
return 1;
}
}
public class C extends A {
public int getValue() {
return 123;
}
}
public class D extends A {
public int getValue() {
return 15234;
}
}
There are about 100 or so subclasses. I also have a manager:
public class Manager {
public static ArrayList<A> list = new ArrayList<A>();
}
How can I "magically" add an instance of all subclasses of A to list without manually creating an instance of every single subclass and adding it to the list? Perhaps with using an Initialization Block?
EDIT
It's not important how I access list in Manager. I edited it to be static.
(2nd attempt - my first attempt was based on a misunderstanding of the Question.)
I'm assuming that what you want to do is build a (static) list that:
contains exactly one instance of each of the subclasses,
is created and populated ahead of time, and
doesn't involve code in each subclass creating / adding an instance of itself to the list.
Firstly, an instance initializer block won't do this. An instance initializer is run when you create an instance ... and something has to new the class (i.e. each of the subclasses) for this to happen.
I think the only viable approach is to write some hairy reflective code that:
iterates over all classes on the classpath,
loads each one using Class.forName(),
reflectively tests to see if the class is a subclass of A,
if it is, reflectively invokes the classes no-args constructor and adds the resulting instance to "the list".
This is (IMO) pretty hacky!! And it is going to be expensive ... unless you can limit the "package space" that needs to be searched for these subclasses.
Actually, this could be a problem that would be better solved using an enum ... especially if the subclasses don't have behavioural differences that require different method implementations. (For instance your getValue() method could just return a private variable ... that you initialize using a constructor.) See #Paul Bellora's answer.
(The thing that would prevent this from being applicable would be if there needed to be multiple instances of some of the subclasses. That's not possible with enums.)
Each class is going to represent a command.
Based on the description of your problem, it sounds like A could be an enum:
public enum A {
B(1) {
#Override
public void execute() {
//code and stuff
}
},
C(123) {
#Override
public void execute() {
//code and stuff
}
},
D(15234) {
#Override
public void execute() {
//code and stuff
}
};
private final int value;
private A(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public abstract void execute();
}
Now, there is exactly one instance of each command, and you can easily iterate commands with A.values().
Although it doesn't quite make sense... one way you can do is, do things similar to Spring's component scanning: make use of things like PathMatchingResourcePatternResolver and find out all possible classes. Iterate through them and add to list if that is a subclass of A.
This is a bit of a hackish way to do it, but if all your subclasses are in one folder (the actual class files) you could iterate over the files in the folder and use the ClassLoader. You code would look something along the lines of -
for(String className : classNames){
Class clazz = classLoader.loadClass(className);
list.add(clazz.newInstance());
}
Look at the ClassLoader API for more info. Also keep in mind that this is not very efficient, but if you are just doing this once you should be fine.
Could be like this :
public abstract class A {
public A(Manager m) {
m.list.add(this);
}
public abstract int getValue();
}
public class B extends A {
public B(Manager m) {
super(m);
}
}
This way you never again have to deal with m.list.add(new A()); while subclassing. But I don't know if this is what you are looking for...
EDIT :
It's not important how I access list in Manager. I edited it to be static.
If you don't care about using singletons, here is a very basic implementation:
But read What is bad about singletons.
public class Manager {
private static Manager instance = null;
protected Manager() {
// Exists only to defeat instantiation.
}
public static Manager getInstance() {
if(instance == null) {
instance = new Manager();
}
return instance;
}
}
Then:
public abstract class A {
public A() {
Manager.getInstance().list.add(this);
}
public abstract int getValue();
}
public class B extends A {
}
But, again this is very not satisfying as a design...
1) You need to find all available subclasses of class A. For that you need to scan all classes on the Java classpath. To make things easier we can assume that all subclasses are in the same location as A.class. A is supposed to be in a jar or in a folder. We can find out its actual location as
URL url = A.class.getProtectionDomain().getCodeSource().getLocation();
2) Lets assume that it is a folder, eg file:/D:/workspace1/x/target/classes/. Now we should walk thru all .class files in this folder and subfolders. We can use File.listFiles or Java 7 NIO2 for that. We have 2 options
a) load each class and check its superclass
Class cls = Class.forName();
if (cls.getSuperClass() == A.class) {
...
b) use javaassist framework http://www.javassist.org or similar to work with class file directly
DataInputStream ds = new DataInputStream(new BufferedInputStream(path));
ClassFile cf = new ClassFile(ds);
String superClass = cf.getSuperClass();
if (superClass.equals("A")) {
Class cls = Class.forName(cf.getName());
...
option b is loads only the classes you actually need, option a is simpler but it loads all classes in the folder
In both cases you create of an instance as
A a = (A) cls.newInstance();
assuming that all subclasses have no-arg constructor
How about using a class path scanner to automatically detect your target classes :
List<Class<?>> classes = CPScanner.scanClasses(new ClassFilter().packageName("com.foo.*").superClass(A.class));
Since you've got the target classes, you can easily initialize them by using newInstance method.
By the way use the maven dependency below to use the given snippet:
<dependency>
<groupId>net.sf.corn</groupId>
<artifactId>corn-cps</artifactId>
<version>1.1.1</version>
</dependency>
Cheers.
This seems like a newbish question, but the last time I worked with Java, the language didn't have generics. I have a class hierarchy (names changed to be as generalized as possible):
public abstract class AbstractBase { .... }
public class ConcreateSubA extends AbstractBase { .... }
public class ConcreateSubB extends AbstractBase { .... }
...
public class ConcreateSubZZ9PluralZAlpha extends AbstractBase { .... }
...
I'm trying to clean up some legacy code, and there's one place where a ton of repetitive duplication can all be factored out into a single routine via generics. (I'm thinking generics because when this routine is called, it needs to operate on only one of the concrete classes.)
The routine looks like
public <Thing extends AbstractBase> void someFunc()
{
another_function_call (Thing.concreteSpecialToken);
// could also be
// another_function_call (Thing.concreteSpecialToken());
// if methods are more feasible than fields
// Cannot use
// another_function_call (Thing().concreteSpecialToken());
// because creating instances of these types is a Major Operation[tm]
}
I'm leaving out about a zillion lines, but that's the important part: someFunc() is type parametric (it actually takes arguments but none of them are Things so no inference). Eventually I need to fetch a special token and this is where I'm getting fuzzy.
The tokens are huge-ass unique strings for each concrete class. They're class-based, not instance-based. The actual token value is declared as a private static final field in each subclass.
So I need to use the public methods/fields of a base class to (eventually) get to the private static field of a subclass. Obviously I can't declare an abstract static method in the base, because that makes no sense. If the data were instance-based, then this would be trivial, with a polymorphic getter in the base class, but the subclass stuff is static.
I feel like I'm missing a feature of Java generics here, but I can't use Thing.whatever() unless the whatever is something that's possible to declare in the abstract base class. I'm running up against either limitations of Java or my lack of expertise trying to bridge the gap. The one attempt I made that seemed promising also had a ton of code duplication all the way down the class hierarchy, defining abstract methods with the exact same code over and over... which is what generics are supposed to help prevent!
I'm running up against either limitations of Java or my lack of expertise trying to bridge the gap.
It's a limitation of Java, although a fairly reasonable one IMO. Basically you're still trying to use static members as if they were polymorphic, and that's not going to work - generics don't help you there.
Options:
Use reflection... but bear in mind that type erasure means you can't get at the Class for Thing unless you pass it in explicitly
If you've got an instance of Thing anyway, just make it an abstract instance member, which in each implementation happens to return the value of a static field
Create a separate type hierarchy which will use instance members
If I understand it correctly, you need the concrete class of the type parameter. The usual way of doing it is to declare your method like this: public <T extends AbstractBase> void someFunc(Class<T> clazz)
This of course means an extra parameter needs to be passed to the method and you need to use reflection to access the static fields, but given Java's type erasure it's the only way.
The moral of the story is that generics and statics don't go very well together.
A bit clunky but if someFunc took a Class<Thing> parameter you could use reflection:
public <Thing extends AbstractBase> void someFunc(Class<Thing> clz) {
// exception handling omitted
Object whatever = clz.getDeclaredMethod("whatever").invoke(null);
But you could maybe take better advantage of polymorphism by using nested classes, something like
public abstract class AbstractBase {
public static class Info {
public String getInfo() {
return "AbstractBase";
}
}
}
public class ConcreteSubA extends AbstractBase {
public static final Info INFO = new Info() {
public String getInfo() { return "ConcreteSubA"; }
}
}
and have someFunc take an AbstractBase.Info parameter.
public <Thing extends AbstractBase> someFunc(AbstractBase.Info inf) {
String info = inf.getInfo();
}
// call it as
ConcreteSubB csb = someFunc(ConcreteSubB.INFO);
The idea is that each class in the hierarchy has a singleton instance of Info holding its formerly-static data.
If you want to keep the token as it is, a private static final field, you can get it through reflection:
public <Thing extends AbstractBase> void someFunc(Class<Thing> clz)
{
try {
Field field = clz.getField("concreteSpecialToken");
field.setAccessible(true);
Object concreteSpecialToken = field.get(null);
another_function_call (concreteSpecialToken);
} catch (IllegalAccessException e) {
handle(e);
} catch (NoSuchFieldException e) {
handle(e);
}
}
At call site, you have to do someFunc(ConcreateSubZZ9PluralZAlpha.class). But I wonder if you can do that, why don't you just pass the token object as a parameter, as in someFunc(ConcreateSubZZ9PluralZAlpha.concreteSpecialToken)? Or maybe even move the method someFunc() to the token class itself.