Can an instance complete its arguments later? - java

I wonder if there is any way that I can declare a new instance with parameters, do not fill them, and just set them later.
Here is an example:
private Example example = new Example() // Need 1 parameter.
public void foo(Object arg1)
{
example = new Example(arg1);
}
It is clear that this is not possible, but is there a way to do something similar to that?

You can always use a parameter-less constructor, and then set the properties of the created instance later.
....
public Example ()
{
this.s = null;
}
public Example (String s)
{
this.s = s;
}
....
public void setS (String s)
{
this.s = s;
}
....
Example ex = new Example ("something");
Example ex2 = new Example ();
ex2.setS("Something Else");

public class Example{
private Object object1;
public Example(){
}
public void setObject1(Object o){
this.object1 = o;
}
}
Now you can use this as follows:
Example example = new Example();
example.setObject1(someObject);

As noted by others and yourself already, there is no easy / official way of object construction when you can't provide the parameters needed.
You may want to look at the Objenesis project. They provide clever ways of instantiation of objects in non-standard ways. To my knowledge sometimes being able to instantiate objects without providing the usually mandatory arguments declared by the constructors.

Related

How to generate methods dynamically in Java

I was wondering, what if I have the following case:
public class MyObject<T> {
private T myTObject;
public void setMyTObject(T m) {
myTObject = m;
}
public T getMyTObject() {
return myTObject;
}
}
And now I want that class to react something like these:
MyObject<ObjectA> objA = new MyObject<ObjectA>();
ObjectA objAInstance = objA.getObjectA();
or
objA.setObjectA(otherObjectAInstance);
Is there a way to dynamically create methods based on T class name?
Or should I better extend ObjectA to MyObject and create those methods using super.get/seMyObject()?
For clarification:
The idea is to have a getter and setter method generated dynamically
so, if I create an instance of:
MyObject<A> objA = new MyObject<A>();
I would be able to call method:
objA.getA();
getA() will call internally getMyTObject() or just return myTObject
so MyObject may react based on T class and generate the corresponding method.
I have updated member attribute to differentiate from MyObject class, it may lead to confusion. also fixed Method return and parameter Type.
Update Answer is completely changed.
Sounds like you want to use something through reflection. The problem with truly dynamically generating the method names is that, as others have commented, it would have to be done in bytecode which means that other classes trying to use your dynamic classes don't have Java code to refer to. It can be done, but it would be a mess.
Instead, here's a possible solution using generics. Please note that this is something of a quick and dirty hack; I leave it to you to refine it. You define an interface with the getters and setters you want, with whatever you want them named:
package com.example.dcsohl;
public interface IntegerWrapper {
public Integer getInteger();
public void setInteger(Integer i);
}
And then, to use them, you use this class to do the heavy lifting. Note that the error checking isn't very good; for example, it doesn't check that "getFoo" at all corresponds to the name of the class being passed in; nor does it validate that the "foo" in "getFoo" matches the "setFoo" method. This is something you can improve on.
package com.example.dcsohl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyWrapper<T> implements InvocationHandler {
Class<T> clazz = null;
T myvalue = null;
public static <W,T> W getInstance(Class<W> clazz, Class<T> clazz2) {
ProxyWrapper<T> wrapper = new ProxyWrapper<T>();
wrapper.setClass(clazz2);
#SuppressWarnings("unchecked")
W proxy = (W)Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] {clazz}, wrapper);
return proxy;
}
private void setClass(Class<T> clazz) {
this.clazz = clazz;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// getter has no arguments
if (method.getName().startsWith("get") && (args == null || args.length == 0)) {
return myvalue;
} else if (method.getName().startsWith("set") && args.length == 1) {
Object o = args[0];
if (o.getClass().isAssignableFrom(clazz)) {
#SuppressWarnings("unchecked")
T val = (T)o;
myvalue = val;
return null;
}
} else {
throw new Exception();
}
return null;
}
}
Finally, to use it, here's a quick sample:
package com.example.dcsohl;
public class Main {
public static void main(String[] args) {
Integer foo = 5;
IntegerWrapper wrapper = ProxyWrapper.getInstance(IntegerWrapper.class, Integer.class);
wrapper.setInteger(foo);
Integer bar = wrapper.getInteger();
System.out.println(bar);
}
}
It seems like a lot of work just to avoid writing simple wrapper classes, and you'd be right, but reflection has its uses, and this is something of a sampler.

Java constructor of "immutable class" with many fields with default values?

I have a JAVA class with lots of fields. They should basically be set at the constructor phase and never change. Semantically the class then is an immutable one.
public class A{
final int a;
final short b;
final double e;
final String f;
final String g;
//and more
}
The problem is that normally these fields have default values and therefore I do not want to always burden the user with a constructor with all of them. Most time, they just need to set a couple of them. There are a couple of ways to solve this:
I would need lots of constructor with different signature.
Create a bunch of set method of these field and only set those non-default value. But this somehow indicate a different semantics other than immutable nature.
Create a new parameter class that is mutable and use that class as constructor.
None of that is totally satisfactory. Is there any other approach? Thanks.
One way
I would use a combination of a parameter class and a fluent builder API for creating the parameter:
public class A {
private final int a;
private final short b;
private final double e;
private final String g;
public static class Aparam {
private int a = 1;
private short b = 2;
private double e = 3.141593;
private String g = "NONE";
public Aparam a(int a) {
this.a = a;
return this;
}
public Aparam b(short b) {
this.b = b;
return this;
}
public Aparam e(double e) {
this.e = e;
return this;
}
public Aparam g(String g) {
this.g = g;
return this;
}
public A build() {
return new A(this);
}
}
public static Aparam a(int a) {
return new Aparam().a(a);
}
public static Aparam b(short b) {
return new Aparam().b(b);
}
public static Aparam e(double e) {
return new Aparam().e(e);
}
public static Aparam g(String g) {
return new Aparam().g(g);
}
public static A build() {
return new Aparam().build();
}
private A(Aparam p) {
this.a = p.a;
this.b = p.b;
this.e = p.e;
this.g = p.g;
}
#Override public String toString() {
return "{a=" + a + ",b=" + b + ",e=" + e + ",g=" + g + "}";
}
}
Then create instances of A like this:
A a1 = A.build();
A a2 = A.a(7).e(17.5).build();
A a3 = A.b((short)42).e(2.218282).g("fluent").build();
Class A is immutable, the parameters are optional, and the interface is fluent.
Two things you can do:
Many constructor overloads
Use a builder object
This is only a semi-serious suggestion, but we can modify mikera's answer to be typesafe.
Say we have:
public class A {
private final String foo;
private final int bar;
private final Date baz;
}
Then we write:
public abstract class AProperty<T> {
public static final AProperty<String> FOO = new AProperty<String>(String.class) {};
public static final AProperty<Integer> BAR = new AProperty<Integer>(Integer.class) {};
public static final AProperty<Date> BAZ = new AProperty<Date>(Date.class) {};
public final Class<T> propertyClass;
private AProperty(Class<T> propertyClass) {
this.propertyClass = propertyClass;
}
}
And:
public class APropertyMap {
private final Map<AProperty<?>, Object> properties = new HashMap<AProperty<?>, Object>();
public <T> void put(AProperty<T> property, T value) {
properties.put(property, value);
}
public <T> T get(AProperty<T> property) {
return property.propertyClass.cast(properties.get(property));
}
}
Aficionados of advanced design patterns and/or obscure Java tricks will recognise this as a typesafe heterogeneous container. Just be grateful i didn't use getGenericSuperclass() as well.
Then, back in the target class:
public A(APropertyMap properties) {
foo = properties.get(AProperty.FOO);
bar = properties.get(AProperty.BAR);
baz = properties.get(AProperty.BAZ);
}
This is all used like this:
APropertyMap properties = new APropertyMap();
properties.put(AProperty.FOO, "skidoo");
properties.put(AProperty.BAR, 23);
A a = new A(properties);
Just for the lulz, we can even give the map a fluent interface:
public <T> APropertyMap with(AProperty<T> property, T value) {
put(property, value);
return this;
}
Which lets callers write:
A a = new A(new APropertyMap()
.with(AProperty.FOO, "skidoo")
.with(AProperty.BAR, 23));
There are lots of little improvements you could make to this. The types in AProperty could be handled more elegantly. APropertyMap could have a static factory instead of a constructor, allowing a more fluent style of code, if you're into that sort of thing. APropertyMap could grow a build method which calls A's constructor, essentially turning it into a builder.
You can also make some of these objects rather more generic. AProperty and APropertyMap could have generic base classes which did the functional bits, with very simple A-specific subclasses.
If you're feeling particularly enterprise, and your domain objects were JPA2 entities, then you could use the metamodel attributes as the property objects. This leaves the map/builder doing a bit more work, but it's still pretty simple; i have a generic builder working in 45 lines, with a subclass per entity containing a single one-line method.
One interesting option is to create a constructor that takes a Map<String,Object> as input which contains the values that the user wants to specify.
The constructor can use the value provided in the map if present, or a default value otherwise.
EDIT:
I think the random downvoters have completely missed the point - this isn't always going to be the best choice but it is a useful technique that has several advantages:
It is concise and avoids the need to create separate constructors / builder classes
It allows easy programmatic construction of parameter sets (e.g. if you are constructing objects from a parsed DSL)
This is a technique that is frequently used and proven to work in dynamic languages. You just need to write decent tests (which you should be doing anyway!)
Having many fields could be an indication that one class does too much.
Maybe you can split the class up in several immutable classes and pass instances of these classes to the constructors of the other classes. This would limit the number of constructors.

calling methods without having reference

if i want to call multiple methods of a one class from another class can i call them by using only 'new classname()' without catching it in class reference?
public class Example {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
new pqr().a=5;
new pqr().b=10;
new pqr().display();
}
}
class pqr
{
int a,b;
public void display()
{
System.out.println(a+" "+b);
}
}
This creates three new objects. Not just one.
new pqr().a=5;
new pqr().b=10;
new pqr().display();
One object with a = 5 and another with b = 10.
Remember you are not working with one object.
Whenever you use new keyword. JVM creates a new object.
if i want to call multiple methods of a one class from another class can i call them by using only 'new classname()' without catching it in class reference?
It's not clear what you mean by "catching it" but you are using a reference... you're just not assigning it to a variable.
In your example, you're creating three different objects - the calculation on your final line just prints 0, because you've only set a and b in other objects. If you want to use a single object for multiple operations, you'll either need to store the reference in a variable, or those operations will have to return "this", allowing you to chain method calls together:
class Sample {
private int a,b;
public void display() {
System.out.println(a+" "+b);
}
public Sample setA(int a) {
this.a = a;
return this;
}
public Sample setB(int b) {
this.b = b;
return this;
}
}
...
new Sample().setA(5).setB(10).display();
This sort of chaining for setters is common in the builder pattern.
You can use the Builder pattern if you want something like that:
NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).
calories(100).sodium(35).carbohydrate(27).build();
The builder pattern is one possibility. The another one is to have static properties so all object will share it's values.
static int a,b;

generics calling constructor

I am trying to do something I would not normally do, it is a bit odd, but I'd like to make it work. Essentially I have a factory that has to create objects by calling the constructor with different types of data (A and B take different types in the code below). I seem to have gotten my self stuck going down the generics route (I do need the code to be as compile time typesafe as possible). I am not opposed to writing the code differently (I'd like to keep the idea of the factory if possible, and I do not want to have to add in casts - so the "data" parameter cannot be an "Object").
Any thoughts on how to fix the code with generics or an alternative way of doing it that meets my requirements?
(Technically this is homework, but I am the instructor trying out something new... so it isn't really homework :-)
public class Main2
{
public static void main(String[] args)
{
X<?> x;
x = XFactory.makeX(0, "Hello");
x.foo();
x = XFactory.makeX(1, Integer.valueOf(42));
x.foo();
}
}
class XFactory
{
public static <T> X<T> makeX(final int i,
final T data)
{
final X<T> x;
if(i == 0)
{
// compiler error: cannot find symbol constructor A(T)
x = new A(data);
}
else
{
// compiler error: cannot find symbol constructor B(T)
x = new B(data);
}
return (x);
}
}
interface X<T>
{
void foo();
}
class A
implements X<String>
{
A(final String s)
{
}
public void foo()
{
System.out.println("A.foo");
}
}
class B
implements X<Integer>
{
B(final Integer i)
{
}
public void foo()
{
System.out.println("B.foo");
}
}
I don't see a way to make it work. I don't really think it should work either. When calling your makeX() function the calling code needs to know what integer parameter corresponds to what type of data to pass in. IOW, your abstraction is very leaky in the first place, and what you're really implementing is a rudimentary form of polymorphism, which you might as well use method overloading for, i.e.:
X makeX(String data) {
return new A(data);
}
X makeX(Integer data) {
return new B(data);
}
Of course it's a toy problem and all that. One way to make it work would be to make the client aware of implementation classes and add a Class<T> argument that you instantiate through reflection. But I suppose that would be kind of defeating the purpose.
I don't think what you're trying to do is possible without casting.
With casting, you have two options
if(i == 0)
{
x = new A((Integer)data);
}
else
{
x = new B((String)data);
}
}
or
class A
implements X<String>
{
A(final Object s)
{
}
}
...
class B
implements X<Integer>
{
B(final Object i)
{
}
}
Probably the closest thing you could get whilst retaining static type safety and having lazy construction is:
public static void main(String[] args) {
X<?> x;
x = aFactory("Hello").makeX();
x.foo();
x = bFactory(42).makeX();
x.foo();
}
private static XFactory aFactory(final String value) {
return new XFactory() { public X<?> makeX() {
return new A(value);
}};
}
public static XFactory bFactory(final Integer value) {
return new XFactory() { public X<?> makeX() {
return new B(value);
}};
}
interface XFactory() {
X<?> makeX();
}
So we create an instance of an abstract factory that creates the appropriate instance with the appropriate argument. As a factory, the product is only constructed on demand.
Clearly something had to give. What would you expect XFactory.makeX(1, "Hello") to do?
This is not possible without casting. As I have said elsewhere - generics don't remove the need for casting, but they mean that you can do all the casting in one place.
In the setup you describe, the factory method is exactly where all the under-the-hood work takes place. It's the spot where your code tells the compiler "I know you don't know what these types are, but I do, so relax.
It's entirely legit for your factory method to know that if i==1, then the data must be be of type Integer, and to check/enforce this with casting.

Casting to Unknown Type When Class Name as a String

public class ExampleClass {
public static void main(String[] args) {
// TODO Auto-generated method stub
Horse hr1 = new Horse();
Horse hr2 = new Horse();
Horse hr3 = new Horse();
Horse hr4 = new Horse();
Set hrSet = new HashSet();
hrSet.add(hr1);
hrSet.add(hr2);
hrSet.add(hr3);
hrSet.add(hr4);
Horse hr;
String hor = "sher_pkg.Horse";
callHorse(hrSet,hor);
}
public static void callHorse(Set xSet,String clsName){
try {
Class hrt = Class.forName(clsName);
Iterator hritr = xSet.iterator();
while(hritr.hasNext()){
exam(hrt.cast(hritr.next()));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static void exam(Object obj){ //I want to use exam(Horse hrr)
System.out.println(obj);
}
}
Here the argument for the exam function is an Object. But I want to have the argument be Horse... so what changes must be done in "exam(hrt.cast(hritr.next()))" method call? I don't want to explicitly use the class name Horse in callHorse()... So what am I supposed to do?
Thanks
Note: Code with sequences of "if (x instanceof MyClass) usually indicates that you are not using polymorphism enough. Code can usually be refactored to get rid of the need to test this. But I'll ignore this for the sake of answering the question asked.
You can do what you are trying to do, but not without some code changes. Method overloading cannot do what you need because in Java, method overloading is decided at compile time. Thus, if you have two methods in a class where both methods have the same name, same return type, but different parameter types, then any code invoking this overloaded method must make explicit which one will be invoked. Your current code does this with the types it provides due to the use of explicit casts but the fully dynamic version does not. If method overloading were decided at runtime, then your code would do what you want. But because it is decided at compile time, your code does not compile.
To solve your problem, you can use generics, or you can restructure your code. First I'll introduce a test harness that shows a very simplified version of what you're starting with:
public class Test {
public void test(Object obj) {
if (obj instanceof Horse) {
Horse c = (Horse) obj;
noise(c);
}
if (obj instanceof Cow) {
Cow c = (Cow) obj;
noise(c);
}
}
public void noise(Horse h) {
System.out.println("Neigh");
}
public void noise(Cow c) {
System.out.println("Moo");
}
public static void main(String[] args) {
Object o1 = new Horse();
Object o2 = new Cow();
Test tester = new Test();
tester.test(o1);
tester.test(o2);
}
}
class Horse {}
class Cow {}
This code runs and does what you would expect. It prints "Neigh" followed by "Moo".
You are trying to replace
if (obj instanceof Horse) {
Horse c = (Horse) obj;
noise(c);
}
with
if (obj instanceof Horse) {
handleNoise(obj, Horse.class);
}
and then adding the method to handle it (simplified):
void handleNoise(Object obj, Class clazz) {
noise(clazz.cast(obj));
}
and as I said before, this doesn't work the overloading of noise is decided at compile time. The compiler sees that you are casting, but does not know at compile time what the type is. So it cannot pick an overloading and compilation fails.
The best way to solve this is by using polymorphism, because polymorphism is decided at runtime. That is, have all of those classes implement some interface and then move the code in question into the individual classes. Here is an example that does this:
public class Test {
public void test(Animal obj) {
obj.noise();
}
public static void main(String[] args) {
Animal o1 = new Horse();
Animal o2 = new Cow();
Test tester = new Test();
tester.test(o1);
tester.test(o2);
}
}
interface Animal {
void noise();
}
class Horse implements Animal {
public void noise() {
System.out.println("Neigh");
}
}
class Cow implements Animal {
public void noise() {
System.out.println("Moo");
}
}
Notice how much simpler the test method is! If you can have each item implement an interface that handles what you call stringProp below, then you can simplify part way:
if (obj instanceof Cust) {
loopOverSet(c.getCustPhonSet());
} else if (obj instanceof Name) {
loopOverSet(c.getCustNameSet());
}
// and so on for the rest...
and then add the method:
void loopOVerSet(Set cxSet) {
if (cxSet != null && cxSet.size() > 0) {
Iterator cxSetIterator = cxSet.iterator();
while (cxSetIterator.hasNext())
{
((StringProp)cxSetIterator.next()).stringProp();
}
}
}
This assumes that the previously-overloaded methods stringProp have been moved into the individual classes CustPhone and CustName and so on and that these classes all implement some interface which I've called StringProp where this interface defines the method stringProp(). Since this code is using overriding instead of overloading it will be decided at runtime.
You might want to take a look at generics.
public static void callHorse(Set<Horse> xSet) {
Iterator<Horse> hritr = xSet.iterator();
while (hritr.hasNext()) {
exam(hritr.next());
}
}
public static void exam(Horse obj) { //I want to use exam(Horse hrr)
System.out.println(obj);
}
Of course in your example you could always just cast the objects. Why you don’t want to do that is beyond me.
When you say:
exam(Horse hrr)
you're telling the compiler that you want it to check all calls to exam() and make sure that each call provides a Horse object as an argument. However, in callHorse(), you're invoking exam() with a dynamically cast argument, and the compiler has no way to check the argument.
It's possible that you could work around this by using reflection and dynamically invoking the exam() method.
You could explicitly cast in the function call -
try {
Class hrt = Class.forName(clsName);
Iterator hritr = xSet.iterator();
while(hritr.hasNext()){
exam((Horse)hrt.cast(hritr.next()));
}
}
but I'm not really sure what you're trying to achieve here - If you're writing code that explicitly references Horses, why do you need to dynamically determine the class type from a string?
First things first,your set should be using either generics or explicitly defined as only holding Horse Objects.
(final Set xSet<Horse>, final String clsName){
...}
Fix that and you have fixed 90% of the issues.
It looks like your design is wrong for Java, and you can't directly do what you are asking for.
Perhaps you need to reshape your code to use the visitor pattern? Failing that, you need to explain your requirement instead of the solution that you want to use. In that way, we can tell you the proper Java solutions to your requirement.
I'm not sure it's possible or desirable to avoid having a reference to "Horse" in the callHorse method. Judging from the printstacktrace after a ClassNotFoundException, you throw a hard error if the class is not found for some reason.
Couldn't you, for the same reason, just cast to "Horse" and then catch the classcastexception if something in the Set is not a Horse?
Can you explain why it exactly is that you need to pass in the classname instead of the class?
Maybe you can also use method overloading, but I'd have to test this, because I'm not entirely sure what the precedence is in this case.
If you are doing a dynamic cast by using Class.cast() with an argument that you're passing to another function, then at compile time nothing is known about the type that you are passing. This is why you cannot use Horse as the argument type where you define the method, but then call the method using reflection in the way that you are. Your cast does very little except verify that -- as long as you don't get an Exception -- the set you pass in is entirely comprised of members of the Class you pass in the name of.
Note that the Class.cast() method was introduced in Java 5, meaning you have access to Generics if you have access to Class.cast(). Generics can help clean things up although they won't solve the problem you are trying to solve.
Using a Java 5 for loop you can rewrite your loop as follows:
public static void callHorse(Set<?> xSet, String clsName) {
try {
Class<?> hrt = Class.forName(clsName);
for (Object x : xSet) {
exam(hrt.cast(x));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
This version is less cluttered and makes your cast more obvious. You are casting to an entirely arbitrary type. The cast may be to any type as long as the class definition can be loaded from the classpath. Thus, if your exam() method takes an argument of Horse then the compiler knows that it cannot guarantee that the call will succeed and the code fails to compile.
Even if you try overloading, it won't work. That is, if you create the methods:
public static void exam(Object obj) {
System.out.println("Object " + obj);
}
public static void exam(Horse obj) {
System.out.println("Horse " + obj);
}
the exam(Object) method will always be the one invoked. Try it.
The bottom line is that what you're trying to do cannot be done. You need to give us more information about exactly what your goal is before we can help you.
Why not write it like this? What exactly are your requirements?
public static void main(String[] args) {
Set<Horse> horses = new HashSet<Horse>();
horses.add(new Horse());
horses.add(new Horse());
horses.add(new Horse());
horses.add(new Horse());
callHorse(horses);
}
public static void callHorse(Set<Horse> horses) {
for (Horse horse : horses) {
exam(horse);
}
}
public static void exam(Horse horse) {
System.out.println(horse);
}
Depending on what you do in the exam() method, it might also make sense to make it an instance method of Horse, like this:
public static void main(String[] args) {
Set<Horse> horses = new HashSet<Horse>();
horses.add(new Horse());
horses.add(new Horse());
horses.add(new Horse());
horses.add(new Horse());
examineHorses(horses);
}
public static void examineHorses(Set<Horse> horses) {
for (Horse horse : horses) {
horse.examine();
}
}
// in Horse.java
public class Horse {
public void examine() {
System.out.println(this);
}
...
}
Is your real goal to have multiple versions of the exam() method, that take different types as parameters, and dynamically select the version needed at runtime?
You can do this explicitly with reflection. Here's an example program.
import java.lang.reflect.*;
public class Test {
public static void exam( Object o ) {
System.out.println( "Object version called" );
}
public static void exam( Test t ) {
System.out.println( "Test version called" );
}
public static void main (String[] args) {
try {
// Create an instance of Test but reference it as an Object
Object untypedTest = new Test();
// Calling exam directly will invoke the Object version
exam( untypedTest );
// But if we use reflection to select the version of exam
// that takes the desired class name, we can invoke it without
// even explicitly casting
String className = "Test";
Class[] examMethodParams = { Class.forName( className ) };
Method examMethod = Test.class.getMethod( "exam", examMethodParams );
Object[] actualParams = { untypedTest };
examMethod.invoke( null, actualParams );
} catch (Exception e) {
e.printStackTrace();
}
}
}
HI,
After searching through i found that dynamic typecast at runtime can't be performed. So what i was trying to figure out seems to be absurd.
I was trying to reduce the cyclomatic complexity of a method1. I was trying to create a method2 which contains the generalized pattern of the repetition pattern found in method1 and calling the method2 from method1 wherever necessary...
the pattern was like this in the first method..
if (obj instanceof Cust)
{
Cust c = (Cust) obj;
Set cxSet = c.getCustPhonSet();
CustPhon cx;
if (cxSet != null && cxSet.size() > 0)
{
Iterator cxSetIterator = cxSet.iterator();
while (cxSetIterator.hasNext())
{
cx = (CustPhon) cxSetIterator.next();
this.stringProp(cx);
}
}
//....pattern continues here... CustPhon is replaced by various classes like CustNam etc... Also getCustPhonSet by getCustNamSet etc...
}
so i thought of writing a generalized method for the above pattern like this::
public void dynamicIteration(Set xlSet, String clsName)
{
if (xSet != null && xSet.size() > 0)
{
try{
Class clsinstance = Class.forName(clsName);
Iterator itr = generalSet.iterator();
while(itr.hasNext())
{
this.stringProp(clsinstance.cast(itr.next()));// See this is wrong.. thats y i posted here by using a simple Horse example
}
}catch(ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
Calling method2 from method 1
//process customer email address
Set cxSet = c.getCustPhonSet();
className = "pkg.CustPhon";
dynamicIteration(cxSet,className);
// Similarly for other patterns
By this way i must be able to reduce the cyclomatic complexity
This is what i was trying to do..
Hey i think this would solve the problem. You need to decide upon which object it is, so that u can call the corresponding operation, right???
Since we use the overriding comcepts the very functionality that s required can be achieved.
What is given by Eddie may be the most appropriate solution for this i guess?
YOu override the method in the respective classes so that on calling it goes the corressponding method.
U got it?

Categories