20

Alright this is kind of a complicated question and I'm completely lost.

Assume you have a string, and a generic class. Like this.

String string;
Class<?> clazz;

How would you check to see if the String represented a value that the class could equal.

For example lets say that:

String string = "true";
Class<?> clazz = Boolean.class;

How would I check and see that the string "true" is in fact a boolean?

Here is another example. Lets say that:

String string = "true";
Class<?> clazz = Integer.class;

How would I check and see that the string "true" is not an Integer?

2
  • Do you want to do the test just for Wrapper types? Commented Aug 7, 2013 at 8:07
  • I'm mainly concerned with the primitive type wrappers, yes Commented Aug 7, 2013 at 8:11

6 Answers 6

20

Given that you want this only for Wrapper Types, you can use some reflection hack here (Exception handling for irrelevant code is ignored here for brevity):

String string = "ABC";
Class<?> clazz = Integer.class;

Method method = clazz.getDeclaredMethod("valueOf", String.class);

if (method != null) {
    try {
        Object obj = method.invoke(null, string);       
        System.out.println("Success : " + obj);

    } catch (InvocationTargetException ex) {
        System.out.println("Failure : " + string + " is not of type " + 
                                          clazz.getName());
    }
}

I'm taking into account the fact that, every wrapper class has a static valueOf method that takes a parameter of type String, and returns the value of that wrapper type. And throws an exception, if the parameter is not convertible to the respective wrapper type.

So, in above case, if an exception is thrown, the string value is not of clazz type.

P.S.: Note that for Boolean.class, any string that is not "true" will be treated as false.

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

Comments

1

I'm assuming you are implementing some sort of Specification/Protocol or similar.

  1. Look at the Spec.
  2. Define a Grammar of valid input
  3. Parse that grammar.

This is similar to what Programming Languages are doing with literals.

Comments

0

In javascript you could eval() the string. In Java you don't have such means. You'll have to implement your own heuristics for this check.

The one thing you can do however, is try to parse the string with the given class. Like:

Iteger.parseInt(stringValue);

If the parse succeeds, then the string can be used as a value for that type. If it fails, then you get an exception. Implement these checks and then deduct some conclusion.

4 Comments

I can't just use that method because I have no idea if the class will be an Integer. It is a generic type.
There is no single line solution for your problem. This is why I say you need to impement a series of checks and then deduct a conclusion.
I'm not expecting a single-line solution. I just think there must be a better way than checking if its any of the primitive types or the other classes I add and then checking it against each and every class I add
You accepted the answer that basically builds on the same idea I suggested. Just uses reflection and builds on the fact that primitive types have the valueOf method. Good, I'm confirmed. However, try not to reinvent the wheel, use JSON or ProtocolBuffers for defining messages. There are lot less error prone and cross platform solutions than writing your own heuristic parser.
0

I'm not able to test this solution right now, but why not something like this? If you can enumerate all of the possible classes yourself, just create some switch statements on the class.

boolean isStringClass (Class clazz, String string) {

    try {
        if (Integer.class == clazz) {
           Integer.valueOf(string);
        } else if (Boolean.class = clazz) {
           Boolean.valueOf(string);
        } [...etc]
    } catch (Exception e) {
        return false;
    }

    return true;
}

Of course you will need to know all of the possible classes, and you will need to know of a method that belongs to that class that is able to parse a String and return its type. For the primitive wrappers that would be valueOf.

If you plan on only converting wrappers, Rohit's solution would be a better choice. However, if you're not doing that and you're unable to add a valueOf method to this new Class, this may be your only option.

Comments

0

I would consider using the JavaBeans PropertyEditor mechanism for this.

@Test
public void testIsOfType() {        
    assertFalse(test("nope", Integer.class));
    assertFalse(test("nope", Boolean.class));

    assertTrue(test("1", Integer.class));
    assertTrue(test("true", Boolean.class));
}

boolean test(String str, Class<?> clazz) {
    PropertyEditor propertyEditor = PropertyEditorManager.findEditor(clazz);
    if (propertyEditor != null) {
        try {           
            propertyEditor.setAsText(str);
            return true;
        } catch (Exception ex) {}
    }
    return false;
}

This avoids the need for explicit reflection, and if you ever decided you needed to test classes other than the primitive wrappers you could register a new editor with PropertyEditorManager.registerEditor().

Unfortunately this still has the problem that Rohit's solution has in that test("1", Number.class) will fail.

Comments

0

Though long time has passed since this question is addressed, I would like to add on to @Rohit answer in the case that the class used doesn't have the valueOf method. One can try the following:

Class<?> aClass = Class.forName("full-class-name");
try {
    Method method = aClass.getDeclaredMethod("valueOf", String.class);
    method.invoke(null, value);
} catch (NoSuchMethodException e) {
    aClass.getConstructor(aClass).newInstance("value");
}

In the second case, the class has to have a constructor that accepts a string.

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.