I have a set of similar classes that all implement a function of the form
public static ClassA convertToClassA(Obj A)
public static ClassB convertToClassB(Obj B)
I want to loop through a list of classes and call this function that takes one argument of Obj in each class. How do I do this given each function is named differently?
Thanks for the help.
Class cls = Class.forName("ClassA");
String methodName = "convertTo" + cls.getSimpleName();
Method method = cls.getDeclaredMethod(methodName, new Class[]{Obj.class});
// If the underlying method is static, then the first parameter is ignored. It may be null as illustrated below.
method.invoke(null, your_object);
Create common interface with your method signature and let your invokable classes implement it, later on you can iterate over your objects as over instances of interface and call methods from it so no problem.
HOWEVER I am starting to think you want to call method without knowing it's name AT ALL - the only knowlage of target method is the number and type of arguments. Well that indeed IS impossible via reflection BUT, it will be innacurate if similar methods signatures will be present. Anyway, don't know what are you trying to do, but your project is badly designed from the ground (no interfaces, poor inharitance I guess etc.)
take a look at the reflection package. it provide methods to get back all the methods an instance has provide.
The apache common's BeanUtil (http://commons.apache.org/beanutils) also provide some util method doing similar things.
Related
I have a class, lets say CargoShip, which is a derived class of 'Starcraft', which implements the interface IStarcraft.
This is the function that should return the count (number of instances) of every ship:
public static void printInstanceNumberPerClass (ArrayList<ISpacecraft> fleet){}
There's a solution which I thought of and I'm sure it will work, declaring 'getCount()' in ISpacecraft, then overriding it in each SpaceCraft ship (I have 4 ships), and just iterating through everyone of them, polymorphism.
Fine, I got that. but because the function is static (yes, I know we dont need to create an object to use it) I thought it might tell me something different. What do I mean by that? Is it possible to create 'static count = 0' instead, in every ship, and somehow access it?
The question is then, how can I access that static field when I get an arraylist of ISpacecraft objects?
Polymorphism doesn't work with static methods, method resolution is very different. For virtual methods on an instance the code may be referring to the object with a variable typed as a superclass or interface, and calling a method is resolved at runtime without your application code needing to know the exact concrete type. For static methods you call it on a specific class and if the method isn't found then it's called on a superclass. Your code has to start with some subclass and resolution works up the hierarchy from there. For static methods you can't not know a low-level class to call the method on, the way you can with instance methods on objects. You can't have the level of abstraction you take for granted with objects.
The comment by markspace provides a much better alternative. Use static methods for stateless functions like java.lang.Math.
I understand what interfaces and abstract classes are, but I don't know how to get the following functionality; if it's possible, that is. I have a bunch of classes which are each going to have a validate() method. Each method may take different parameters. For example, we could have classes with the following methods:
boolean validate();
boolean validate(Block[]);
boolean validate(BlockSet[]);
...
So, basically I want to know if I can use an interface or abstract class, or something else, to define a contract to have a method with a given name and return type implemented, but no restrictions on the set of parameters. Thanks in advance.
You can do this with validate(Object... args), but it's worth questioning whether you really want to. Interfaces and Abstract Classes are useful so that you can group a bunch of similar objects together, and have implementations do different things with the same operation. It seems to me that you wouldn't be able to call this method without knowing what the underlying implementation is, and therefore there is no reason to abstract them.
Try using varargs in an interface:
boolean validate(Object... args) or
'boolean validate(Block... blocks)`
if the Blocks are always a collection, use their supertype:
boolean validate(Collection<Block> blocks)
But then you may need to use some casts. Not best option.
If you want method to take any number pf parameters then you can use Varargs but if you want it to change Type also then its not feasible.
Also what you want to achieve is find a separate way of method overloading, but for that you will have to explicitly specify the methods.
I have a bunch of classes extending an abstract Base class.
Each subclass takes an array as in the constructor, (different length depending on class).
These classes could be written by other people.
What is the best way to figure out the length of the array the class needs?
I could:
(A) Require that each derived class have a static method, returning the length.
However, the base class cannot enforce this, since abstract static methods does not work in java.
(B) Each derived class have a constructor with no arguments, and I construct
such classes just to be able to call the countParameters() method, that
I can enforce from the Base class. This feels "cludgy", since I am not interested in creating such object, but only need some info about it.
The reason is that I am creating a GUI, that gives the user the ability to create
instances of Derived classes, but each Derived class takes different number of parameters.
That is, I need to know how to draw the GUI before I can create the classes.
EDIT:
I could just require that each Derived class have a private
constructor, with no arguments, and using reflection I can call the countParameters() method.
EDIT2: Actually, what I am interested in, is what the names of the parameters are.
That is, if the class Derived have the constructor
public Derived(double name1,double name2,...)
I need a way to generate the String[] array
{name1,name2,...}
I guess this would be impossible to do without creating an instance of the class,
but for the user to be able to create such class, he/she needs the parameter names!
Moment 22.
It sounds like you need the Factory Pattern.
In general, it's a bad idea for a base class to know the set of it's descendant's. So you define another class whose job it is to know that.
If you have something like a Shape, with ThisShape and ThatShape as derived classes, then a ShapeCreator will handle the job of creating the specific set of shapes your program supports, giving each one the arguments it needs.
It's not quite clear what you're trying to achieve, but I wonder: Do the subclasses really have to take a single parameter with an array, as opposed to a list of parameters?
Constructor<?> ctor = Test.class.getConstructors()[0];
int parameterCount = ctor.getParameterTypes().length;
ctor.newInstance(new Object[parameterCount]);
how about this code:
public absract Base {
public abstract int size();
public Base(Object[] objs) {
if (objs.length != size()) {
throw new IllegalArgumentException();
}
//rest of your code.
}
each child class needs to implement size method.
hope its help.
I'd go with method A. You can't get the compiler to enforce the existence of such a method, but you can certainly enforce it in your program - no method, no work!
Seriously, this whole scheme is a bit brittle and I can't think of a way to make it significantly better. An incorrect implementation of those subclasses will bomb out, that's life.
A possible remedy would be for you to provide a set of interfaces for those subclasses, such as
SubClassTaking2Args
SubClassTaking3Args
...
and requiring your sub's to implement one of those as a marker interface. But that's just more bureaucracy with little more effect.
I am storing a list of classes through (Classname.class) and would like to instantiate one? Is this possible?
newInstance seems to the method I am after but it doesn't support a constructor?
You can use Class.getConstructors (or Class.getConstructor) to get a list of available constructors, and invoke any of them with Constructor.newInstance, which does accept parameters.
Just to add one point I see missing:
You can invoke newInstance directly on the Class object if it has a public null constructor. (Null constructor is the constructor with no arguments.)
Otherwise, you can find constructors via Class.getConstructors() as others have said.
The Java tutorial on reflection covers this well. But yeah, basically Class.getConstructors, then Constructor.newInstance is where it's at.
Java is designed so you can never "trick" it as long as you use the java.lang/java. classes or other standard libraries. One of the most important things of OOP is that objects should be in a defined state, thus you can be safe that the constructor is always run. Even if you're using some strange-looking reflection libraries to get your work done.
So, using Class.forName("me.Test").newInstance(); (or similar) will under-the-hood invoke the Test() constructor for you.
If you want to invoke another constructor the code is something like:
Test test = (Test)Class.forName("Test").getConstructor(String.class).newInstance("Hello World");
Here the getConstructor asks what the constructor looks like (it wants a string) and then you call it with a string.
You cannot construct new classes this way.
If you have the name of a class you can use Class.forName(className) to load/reference a class.
If you have the byte code for a class you want to create you can have a class loader load the byte code and give you the class. This is likely to be more advanced than you intended.
If you have a list of Class objects obtained through class literals, you might as well statically reference the constructors rather than slipping into reflection evilness.
Lets say you have a class SomeClass which has its own implementation of toString(), and also has the ability to parse a new instance of itself by reading that same string.
Which of these methods do you prefer, or find better to use?
You can either define it as another constructor:
public SomeClass(String serializedString);
or you can define it as a static method, which in turn creates a new instance (by one of the other constructors, does some with it, and returns the new instance:
public static SomeClass toObject(String serializedString);
Does it even matter? (my hunch is there is no case this matters, but I am trying to make sure)
My own preference is to keep the parsing logic out of the constructor. That way it can call the appropriate constructors (possibly private) as necessary. It doesn't have to depend on default object construction and so on. So I would go with the toSomeClass() method.
Also, it is not immediately clear that SomeClass(String) will parse an object based on the serialization string. There may be many other meanings to a constructor which takes a String. The toSomeClass() static method makes this clear.
I agree with Avi's recommendation. I'd like to add two more advantages:
A static factory method allows you to return null, which a constructor can't.
A static factory method allows you to return a subclass of its defined return type, which can help provide forward compatibility.
One exception: if you're writing a simple value type and using the immutable pattern, I see no reason to use a static factory method.
The static method has the advantage that you can then use the string-reading constructor for something else. Also in general it's better to use static factories than constructors in any nontrivial classes. It gives you more flexibility.
A Java convention for such static methods is:
public class Foo {
// ...
public Foo parseFoo (String s) {...}
// ...
}
as in the standard parseInt(...), parseLong(...), parseDouble(...), etc. Unfortunately, Sun also gave us a different convention with the wrapper classes, as in Boolean.valueOf(...). However, I'd pick one of those conventions and follow it consistently.
To keep some specific logic (like parsing from string) out of constructor is good design policy.
Constructor job is mainly object creation. Initialization and creation of it's fields.
Serialization logic need to be separated from creation. Firstly you may wan't to create separate static method, secondly in evolution of your class you may want to implement some kind of Serializable interface and delegate reading/writing job to another class.
Another advantage to a static constructor is that you can give it a meaningful name. In this case, I would suggest parse:
SomeClass inst = SomeClass.parse("wibble");