I am using Java Reflection to initialize different types of objects. All of these objects are constructed the same way (namely, I pass in the same values to construct them).
Thus, my injector looks through each of the fields, and does a long if/else statement like the following:
if (Foo.class.isAssignableFrom(field.getType())
return new Foo(values);
else if (Bar.class.isAssignableFrom(field.getType())
return new Bar(values);
else if...//Continue over and over
I can't define an interface that requires the class to have a factory, because factories are static by nature. The same holds true for extending an abstract class.
Is there some way I can remove the above if/else statement so my injecting class has no idea about the classes that need injecting (besides the fact that it can be constructed with values?
As requested:
Have you looked at the Spring source code? This is a problem that has already been solved by an existing open source project and you can just fork the code and re-use it.
Use something like (untested):
private <T> T newInstance(Class<T> type){
Constructor<T> constructor = type.getConstructor(valueTypes);
return constructor.newInstance(values)
}
Then call:
Object obj = newInstance(field.getType());
where valueTypes are the types of the values.
Related
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.
I have a design question to ask. I so far have not written any code, just thinking about how to implement at this point. I have an object of type A and it contains an object of type B. I would like B to define a category of objects (Interface or abstract class?). I then have an xml file that defines the sub-type that B should be. For instance, if B is an interface named Driveable, then "car" or "truck" might be defined in the xml as the Drivable object needed for type A.
What I was thinking of doing is making B an interface and then creating a static factory class that has a factory method to determine what sub-type B should be given an xml file. So my first question is would this be the best way to approach the problem? Would it be better to use an abstract class instead of an interface or is it mainly just personal preference?
Second, if I do go with an interface, then inside my factory method would I just do:
B createB(File f){
...
String type = ...
if(type.equals("car"))
return new CarType();
else if(type.equals("truck"))
return new TruckType();
...
return null;
}
So every time I add a new B sub-type, I would need to add another if statement to this method. Is there a better way to do this so all I would have to do is create a new B sub-type and then update my xml and not update the factory method? I essentially dont want to hard code in the types of B into my factory method. If what I have above is pretty standard protocol with factory methods, then I can deal with doing it that way, just doesnt quite seem right.
What you could do is define in xml the actuall classname that you want the B impls to be and then use the generic class constructor like this (missing error handling):
String bimplClassname = //read from xml
Class bimplClass = Class.forName(bimplClassname);
B newB = bimplClass.getConstructor(/*arg types*/).newInstance(/*args*/);
Growing off of carnold's example, your could create a map in your Factory Class that maps between the text in the xml and the corresponding java class.
private final static Map<String, Class> typeMap;
static {
typeMap = new HashMap<String, Class>();
typeMap.put("car", CarType.class);
typeMap.put("truck", TruckType.class);
}
and then in your method:
B createB(File f){
...
String type = ...
Class clazz = typemap.get(type);
if (clazz == null){
return null;
}
B newB = clazz.getConstructor(/*arg types*/).newInstance(/*args*/);
return newB;
}
Slightly easier to maintain than the if/else, but still have to maintain it.
I guess it depends on what triggers the creation of your objects. If it is some text that triggers the creation, then your existing code is fine for a small application. You could also choose a dependency injection framework like Guice.
Also, note that for comparing strings, you should use the .equals method, not == as shown in your code.
What I wanna do is a method that can
generate instance of Class X (a class variable passed in arg) and
override some of it's method
More specifically, the parent class X I want to override contains
Contains no default constructor (e.g. all constructors with args)
Constructors calling non-private method within the same class
Originally I thought it's quite simple to use reflection or something similar,
Then I found there's limitation on implementing my requirement.
For refection: Can only override "interface" via java.lang.reflect.Proxy
http://download.oracle.com/javase/1.3/docs/guide/reflection/proxy.html
for cglib: it cannot create instance of no default constructor and constructor calling non-private member methods
http://insufficientinformation.blogspot.com/2007/12/spring-dynamic-proxies-vs-cglib-proxies.html
I think this is achievable, since Mockito can do all kinds of method injection runtime.
Please anyone give some advise, Thanks.
The pseudo-code I image is like this:
createAndOverride(Class X) {
X newObj = X.newInstance(args) {
#override
methodOfX(args2) {
...
}
}
return newObj;
}
Original problem scenario
I was intended to test a Class which has several methods calling X1.get(), X2.get(), X3.get()
In some test case, I need to make Xn.get() to return something I can control for test (e.g. null)
Due to below constraint:
But due to mock tool restriction to JMock 1.0 (I have no control :( ), so I cannot just simply mock Xn.get() to returns "someSpecifiedObjects"
Xn has no null constructors and constructors calling non-private member
My workaround is self made Xn Class and pass them to test case to let Cn.get() to be expected
code example:
ClassToTest.SomeMethod(new X1() {
#override
get() {
return someSpecifiedObjects;
}
});
And this kind of thing is spread-ed over the Test Case.
Therefore, In order to reduce duplicate code, I would like to build a method to generate Xn instance with specified overrided method for test. e.g.
X1 x1 = createAndOverride(X1);
Then, the problem of this post comes
are you looking for something like javassist? You can instrument code and inject your methods at runtime. I personally try to avoid byte code manipulation as much as possible. Can you not have these overrides in your code base rather than doing on the fly? May be something like wrappers?
So what I think you need is a similar functionality to C#'s Reflection.Emit:
Using Reflection.Emit to create a class implementing an interface
Java Equivalent of Reflection.Emit
Dynamically Create Java Classes With JavaClassCreator
While I haven't done this myself, I think you should be able to use reflection/emission and dynamic type creation in order to achieve what you're looking for. However, I would still like to mention that if you're trying to test "functionality" that's not int he code path of the function you're testing, then you probably shouldn't be testing it at all. For example:
SomeObjectInterface get()
{
if(_someObjectStateIsSet)
{
// Return a concrete implementation A
return new ConcreteImplA();
}
else
{
// Return a concrete implementation B
return new ConcreteImplB();
}
}
In this case get has no code path that would return null, so you shouldn't need to test for null. I'm not sure if I understood your question 100% correctly, especially why you're testing for null, but consider the above advice and see what works for you.
First of all please forgive me if its a really dumb question, I am just trying to learn this language to its core. I am reading Effective Java and the very first chapter talks about Static factory methods vs. Constructors. Their pros and cons. Few things that are confusing to me are:
class of an object returned by static factory method is nonpublic - what exactly does it mean?
unlike constructors static factory methods are not required to create a new object each time they are invoked - How does this happen? I am invoking factory method only to obtain a new object and do we put a check in factory method for checking if object already exists?
Thanks.
class of an object returned by static factory method is nonpublic -
what exactly does it mean?
It means that the actual class of the objects returned by a static factory method can be a subclass of the declared type, and this subclass does not have to be public. It's just another implementation detail that client code should not care about.
unlike constructors static factory methods are not required to create a new object each > time they are invoked - How does this happen? I am invoking factory method only to obtain a new object and do we put a check in factory method for checking if object already exists?
Yes, that's one way this could be done. But really, anything is possible.
First off, kudos to you for your choice in Java-lit: Bloch's book is an excellent primer.
To answer your 2nd question ('unlike constructors static factory methods are not required to create a new object each time they are invoked'), it's important to realize that what Bloch is saying here is that with a static factory you have the option of either: returning a new object or returning a pre-existing one. It all depends on what you want to do.
For example, let's suppose you have a really simple value class of type Money. Your static factory method probably should return a new instance -- that is, a new object with a specific value for Money. So, like this:
public class Money {
private Money(String amount) { ... } /* Note the 'private'-constructor */
public static Money newInstance(String amount) {
return new Money(amount);
}
}
But let's say you have some object that manages some resource and you want to synchronize access to that resource through some ResourceManager class. In that case you probably want your static factory method to return the same instance of itself to everyone -- forcing everyone to go through that same instance, so that that 1 instance can control the process. This follows the singleton-pattern. Something like this:
public ResourceManager {
private final static ResourceManager me = new ResourceManager();
private ResourceManager() { ... } /* Note the 'private'-constructor */
public static ResourceManager getSingleton() {
return ResourceManager.me;
}
}
The above method forces your user to only ever be able to use a single instance, allowing you to precisely control who(and when) has access to whatever it is you are managing.
To answer your first question, consider this (admittedly not the best example, it's pretty ad-hoc):
public class Money {
private Money(String amount) { ... }
public static Money getLocalizedMoney( MoneyType localizedMoneyType, String amount ) {
switch( localizedMoneyType ) {
case MoneyType.US:
return new Money_US( amount );
case MoneyType.BR:
return new Money_BR( amount );
default:
return new Money_US( amount );
}
}
}
public class Money_US extends Money { ... }
public class Money_BR extends Money { ... }
Note how I can now do this:
Money money = Money.getLocalizedMoney( user_selected_money_type );
saveLocalizedMoney( money );
Again, a really contrived-example but hopefully it helps you see more or less what Bloch was getting at with that point.
The other answers were good -- I just think that, as a beginner, sometimes it helps to see some actual code.
When you use the new keyword then you as the developer know that the JDK will create a new instace of that object. What the author is saying, when you use a static method, the developer no longer knows if the method is creating a new instance or possibly doing something else. Something else can be, reusing cached data, object pooling, creating a private implementation and returning a subclass of the class.
class of an object returned by static factory method is nonpublic
Frequently a static factory method will return either an an object typed as an interface (most common), or sometimes some base class (less common). In either case, you don't know the exact class of the returned object.
The advantage of this is getting an object whose behaviour you know without worrying about the messy details of what class it instantiates.
unlike constructors static factory methods are not required to create a new object each time they are invoked
To understand this, consider the case of working with a singleton. You may call .getInstance() on some factory classes to get the singleton instance of an certain object. Typically, what this does is create an instance of the object if it doesn't already exist, or give you the existing instance if it already does. In either case, you get back a copy of the object. But you don't (and won't) know if this singleton had to be created, or if one had already been constructed previously.
The advantage of this is that the lifecycle of the object and when it is created is managed for you.
Both of your questions can be answered by looking at some code that makes use of both of these properties of static factory methods. I suggest looking at Guava's ImmutableList.
Note how the no-arg factory method of() always returns the same instance (it doesn't create a new instance each time). If you look carefully, you'll also notice that its copyOf(Iterable) factory method actually returns the object that is passed to it if that object is itself an ImmutableList. Both of these are taking advantage of the fact that an ImmutableList is guaranteed to never change.
Notice also how various factory methods in it return different subclasses, such as EmptyImmutableList, SingletonImmutableList and RegularImmutableList, without exposing the types of those objects. The method signatures just show that they return ImmutableList, and all subclasses of ImmutableList have package-private (default) visibility, making them invisible to library users. This gives all the advantages of multiple implementation classes without adding any complexity from the user's perspective, since they are only allowed to view ImmutableList as a single type.
In addition to ImmutableList, most instantiable classes in Guava utilize static factory methods. Guava also exemplifies a lot of the principles set forth in Effective Java (not surprising, given that it was designed by those principles and with guidance from Josh Bloch himself), so you may find it useful to take a look at it more as you're working through the book.
I am reading a Stream, which provides an identifier (a simple int). Depending on the int different data follows, which i need to turn into objects. So far i created classes for each object type, and each class provides a read(InputStream input)-method which reads whatever data there is to be read for that kind of object (all object classes inherit from a common base class).
However, there are numerous id's and thus numerous classes. What is the most elegant way to determine and create the instance of the class?
The most naive approach i tried first was to have a switch-case block to create the instances, but i find that it clutters the code (unreasonably). It also forces me to have every class available at compile time.
Second try was to create a map that maps each int to a class and use newInstance() to create the objects. There is still the problem that i need to initialize the map, which still requires that i have every class available at compile time. It more or less just moved the clutter from one place to another.
Removing the compile time dependencies is not required, it would just be a bonus if possible. The main goal is to avoid the boilerplate code.
Constraints: I don't want to add a library to solve this. Reflection is fine with me.
An alternative approach is to still use a Map but essentially use late-binding, if that's preferable. You could even store the config in a properties file like:
1=java.lang.String
2=my.class.Something
...etc...
You then do something like this:
Map<Integer,ObjectFactory> loader = ... // load from properties; fairly trivial
assuming:
public class ObjectFactory {
private Final String className;
private transient Class clazz;
public ObjectFactory(String className) {
this.className = className;
}
public Object createInstance() {
try {
if (clazz == null) {
clazz = Class.forName(className);
}
return clazz.newInstance();
} catch (Exception e) {
throw new IllegalStateExxception("Could not crate " + className, e);
}
}
}
I think your map solution sounds fine, but move the initial map setup out of of the Java code and into a config file. (Class.forName will help here)
You could have a registry with prototypes.
A prototype of each class you want to be able to create (at a point in time) could be added to your registry object at runtime, these prototypes would each have their own unique integer id.
When you want an object of id x, you just ask of your registry object to clone and return the prototype which id is x. (or null if no such prototype is currently registered).
Internally the registry could be a (hash)map for quick retrieval, but it could just as easily be a list of prototypes (Do make sure of course that all prototypes implement a common interface the registry can work with). Best thing is, no need for reflection!