11

Is there a straight-forward way to implement a method with the following signature? At minimum, the implementation would need to handle primitive types (e.g. Double and Integer). Non-primitive types would be a nice bonus.

//Attempt to instantiate an object of type T from the given input string
//Return a default value if parsing fails   
static <T> T fromString(String input, T defaultValue)

Implementation would be trivial for objects that implemented a FromString interface (or equivalent), but I haven't found any such thing. I also haven't found a functional implementation that uses reflection.

4
  • Why are you trying to return <T> T instead of just T? Commented Mar 30, 2012 at 21:50
  • @Makoto This is a generic method. <T> declares a type variable for the method. The return type is declared simply as T. Commented Mar 30, 2012 at 21:53
  • Fair enough. Now I understand, thanks. Commented Mar 30, 2012 at 21:54
  • @Caleb: Nothing simple and totally general. Commented Mar 30, 2012 at 22:47

3 Answers 3

11

That's only possible if you provide Class<T> as another argument. The T itself does not contain any information about the desired return type.

static <T> T fromString(String input, Class<T> type, T defaultValue)

Then you can figure the type by type. A concrete example can be found in this blog article.

Sign up to request clarification or add additional context in comments.

5 Comments

Yes, the type would be needed, unless the API requires that defaultValue is non-null.
@DilumRanatunga Can you elaborate? I can see how passing a null value would make type inference impossible, but I don't see how it'd solve the issue of determining the concrete type of T.
Use defaultValue.getClass() to get the type as Class<T>.
Hmm, testing this, defaultValue.getClass() returns an instance of type Class<capture#1-of ? extends Object>. Is the unchecked cast to Class<T> avoidable?
This information is lost during runtime. Every T is then just Something which extends Object. Just keep the unchecked cast or add a Class<T> argument, it's also nicer and avoids problems with null default value (in your particular case, you namely already know T when you invoke the method, how else would you be able to specify a default value?).
1

You want an object that parses a particular type in a particular way. Obviously it's not possible to determine how to parse an arbitrary type just from the type. Also, you probably want some control over how the parsing is done. Are commas in numbers okay, for example. Should whitespace be trimmed?

interface Parser<T> {
    T fromString(String str, T dftl);
}

Single Abstract Method types should hopefully be less verbose to implement in Java SE 8.

1 Comment

Fortunately, fine control over the parsing mechanisms is unnecessary for my purposes. It's sufficient to fall back to a default value if parsing fails.
1

Perhaps not answering the question how to implement the solution, but there is a library that does just this (i.e has almost an identical API as requested). It's called type-parser and could be used something like this:

TypeParser parser = TypeParser.newBuilder().build();

Integer i = parser.parse("1", Integer.class);
int i2 = parser.parse("42", int.class);
File f = parser.parse("/some/path", File.class);

Set<Integer> setOfInts = parser.parse("1,2,3,4", new GenericType<Set<Integer>>() {});
List<Boolean> listOfBooleans = parser.parse("true, false", new GenericType<List<Boolean>>() {});
float[] arrayOfFloat = parser.parse("1.3, .4, 3.56", float[].class);

Comments

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.