0

I'm very new to Java (~10 days), so my code is probably pretty bad, but here's what I've got:

ArgsDataHolder argsData = new ArgsDataHolder();  // a class that holds two
                                                 // ArrayList's where each element
                                                 // representing key/value args
Class thisArgClass;
String thisArgString;
Object thisArg;

for(int i=2; i< argsString.length; i++) {
    thisToken = argsString[i];
    thisArgClassString = getClassStringFromToken(thisToken).toLowerCase();
    System.out.println("thisArgClassString: " + thisArgClassString);
    thisArgClass = getClassFromClassString(thisArgClassString);

    // find closing tag; concatenate middle
    Integer j = new Integer(i+1);
    thisArgString = getArgValue(argsString, j, "</" + thisArgClassString + ">");

    thisArg = thisArgClass.newInstance();
    thisArg = thisArgClass.valueOf(thisArgString);
    argsData.append(thisArg, thisArgClass);
}

The user basically has to input a set of key/value arguments into the command prompt in this format: <class>value</class>, e.g. <int>62</int>. Using this example, thisArgClass would be equal to Integer.class, thisArgString would be a string that read "62", and thisArg would be an instance of Integer that is equal to 62.

I tried thisArg.valueOf(thisArgString), but I guess valueOf(<String>) is only a method of certain subclasses of Object. For whatever reason, I can't seem to be able to cast thisArg to thisArgClass (like so: thisArg = (thisArgClass)thisArgClass.newInstance();, at which point valueOf(<String>) should become accessible.

There's got to be a nice, clean way of doing this, but it is beyond my abilities at this point. How can I get the value of the string loaded into a dynamically-typed object (Integer, Long, Float, Double, String, Character, Boolean, etc.)? Or am I just overthinking this, and Java will do the conversion for me? :confused:

TimFoolery
  • 1,895
  • 1
  • 19
  • 29
  • [Off-topic]: Classes should be named using UppercaseStartingCamelCase (so `argsDataHolder` should be `ArgsDataHolder`). – Greg Kopff Jun 04 '12 at 04:17
  • A static method on which class? The various "boxed" objects (Integer, Long, Boolean) etc have `valueOf()` methods, but they're (a) static and (b) don't have a common ancestory. You'd have to reflectively call the method, rather than `thisArgClass.valueOf(thisArgString)`. – Greg Kopff Jun 04 '12 at 04:21
  • You have two successive lines that assign a value to `thisArg` -- is that a "typo"? – Greg Kopff Jun 04 '12 at 04:22
  • Michael, If you know that variable type of the right side is an Integer, Long, Float, Double, String and whatever, thisArg = (String) thisArgClass will work. If you dont know then you have to use instanceOf -- http://www.java-samples.com/showtutorial.php?tutorialid=332 – vajapravin Jun 04 '12 at 04:23
  • @vajapravin: can you write that up as an answer (with more detail), because I don't understand your comment. – Greg Kopff Jun 04 '12 at 04:24
  • @GregKopff Sorry I deleted that because it looks like I did indeed already try calling it as a static method, and yeah, it didn't work. Umm... reflectively call it... so... `Method valueOfMethod = thisArgClass.getMethod("valueOf", String.class); thisArgClass = valueOfMethod.invoke(null, thisArgString)`? – TimFoolery Jun 04 '12 at 04:25
  • @vajapravin I think you are converting the wrong way. I am not wanting to convert a dynamic type to a String, but rather I want to convert a String to a dynamic type. – TimFoolery Jun 04 '12 at 04:28
  • Michael: that's along the lines I meant yes - (sorry I don't have time at the moment to write you a fragment that I know works, or I'd have posted you an answer by now!) – Greg Kopff Jun 04 '12 at 04:34
  • see this http://stackoverflow.com/questions/2127318/java-how-can-i-do-dynamic-casting-of-a-variable-from-one-type-to-another – vajapravin Jun 04 '12 at 04:35
  • Are you sure you need to use reflection? This seems extremely advanced for someone with only 10 days experience in Java. – Jim Garrison Jun 04 '12 at 04:45
  • @JimGarrison Your method compiled. I can only assume that it works. Will let you know when I get this up and running! (You get a +1 for now. ^_^) – TimFoolery Jun 04 '12 at 05:04
  • @JimGarrison RE: it being advanced: It is indeed pretty tough! I'm basically adding functionality to an example program (which already utilizes reflection) in an OReilly book (Learning Java, Third Edition). They take the training wheels off in a hurry. (I'm on page 210 out of ~875... only 25% done, so I can only imagine I'll be in way over my head soon.) I consider myself to be pretty smart, but I'm struggling with this book. It's definitely not for beginners. – TimFoolery Jun 04 '12 at 05:15

2 Answers2

1

I can't seem to be able to cast thisArg to thisArgClass (like so: thisArg = (thisArgClass)thisArgClass.newInstance();,

This will not work like this as you need to initialize thisArgClass first.This will produce compile time error. Change the code something like this:

Class thisArgClass = null;
try {
    Object thisArg = thisArgClass.newInstance();
} catch (InstantiationException ex) {
    Logger.getLogger(Test3.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
    Logger.getLogger(Test3.class.getName()).log(Level.SEVERE, null, ex);
}

Hope this will help you.

UVM
  • 9,776
  • 6
  • 41
  • 66
  • Sorry... the `...` in the code was supposed to represent the parts where variables are assigned values. I'll add that in to make that more clear. – TimFoolery Jun 04 '12 at 04:31
  • @Michael OK so that it will be more clear to others as well and chances of getting answers will be more. – UVM Jun 04 '12 at 04:34
1

There are several things wrong here. I'll assume that thisArgClass has been set correctly; for your example it would contain Integer.class. In order to invoke newInstance() on a Class object, the class must have a no-arg constructor. Class Integer does not have such a constructor, so you have to invoke one of the existing constructors using a more roundabout method:

Constructor<Object> c = thisArgClass.getConstructor(String.class);
Object i = c.newInstance(thisArgString);

Since you don't know the actual type of the object until runtime you must use <Object> and cast the result to the desired type before using the value.

Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
  • I tried something like this earlier, but it didn't work. I think I passed getConstructor() the wrong parameter type. Will try your solution here in a sec. – TimFoolery Jun 04 '12 at 04:53