2

I know if I were in PHP I would be able to create an object as following:

// class Name
$var = "Name";
$my_name = new $var("John", "Doe");

Now, I wanted to adopt similar approach in Java. I have a file which I need to parse and produce objects depending on the line read from the file. For example:

2235:org.powertac.common.TariffSpecification::8::addRate::9
2235:org.powertac.common.Tariff::8::new::8
2235:org.powertac.common.TariffSpecification::10::new::1::PRODUCTION
2236:org.powertac.common.Rate::11::new
2236:org.powertac.common.Rate::11::withValue::0.015
2236:org.powertac.common.Rate::11::setTariffId::10
2236:org.powertac.common.TariffSpecification::10::addRate::11
2236:org.powertac.common.Tariff::10::new::10
2247:org.powertac.common.RandomSeed::12::init::DistributionUtilityService::0::model::-7651755067434358
2257:org.powertac.genco.Genco::13::new::nsp1a::true::true
2258:org.powertac.genco.Genco::13::new::nsp1a
2258:org.powertac.genco.Genco::15::new::nsp1b::true::true

then I should create an object of the type Rate, (new), with default values. Therefore, parsing that line would yield me: "org.powertac.common.Rate"(String) and I wanted to create a org.powertac.common.Rate object. How could I do it? I know it's a lazy evaluation ... how can I create something similar in Java?

1
  • 3
    You're looking for reflection. Commented Aug 27, 2012 at 19:13

2 Answers 2

3

Use the Java Reflection API:

String className = "org.powertac.common.Rate";
String ctorArg = "8";
Class<Rate> clazz = (Class<Rate>) Class.forName(className);
Constructor<Rate> ctor = clazz.getConstructor(String.class);
Rate rate = ctor.newInstance(ctorArg);

Then, if you want to invoke a method using Reflection:

String methodName = "setTariffId";
String methodArg = "1";
Method setTariffId = clazz.getMethod(methodName, String.class);
setTariffId.invoke(rate, methodArg);
Sign up to request clarification or add additional context in comments.

5 Comments

@philippe: But don't you have the name in a variable after parsing the line?
I do ... but how could I create for example: Rate rate = (Rate) Class.forName("org.powertac.common.Rate").newInstance();
Instead of "org.powertac.common.Rate" use the name of the variable which holds that value.
For example, org.powertac.common.Tariff::8::new::8 has: org.powertac.common.Tariff is the class name, 8 is the order it is being executed, and 8 is the argument to the constructor, how could I create a Tariff object with that argument?
@philippe: I've put up an example.
1

It may be easier to use some preexisting serialization / deserialization solution in Java, but here's something that would work for your String based approach:

Class<?> rateClass = class.getClassLoader().loadClass("org.powertac.common.Rate");
Constructor<?> constructor = rateClass.getConstructor(String.class);

Rate rate = (Rate)constructor.newInstance("Value")

So in this case:

2258:org.powertac.genco.Genco::15::new::nsp1b::true::true

you would do the following:

String className = "org.powertac.genco.Genco";
Object[] args = {"nsp1b", true, true};

Class<?> rateClass = getClass().getClassLoader().loadClass(className);
Constructor<?> constructor = rateClass.getConstructor(String.class, boolean.class, boolean.class);

Object deseraliazed = constructor.newInstance(args);

You may want to store the type along with the constructor values.

2 Comments

Johncarl I've updated my question ... There is also the arguments for the constructor, which goes after the new keyword
Right, the constructor arguments are represented by the class type in the getConstructor() method, and the value in-order in the newInstance() method.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.