I want to get an instance to an enum type, so that:
String enumString="abc";
MyClass.MyEnum enumType=Class.forName("com.MyClass.MyEnum."+enumString);
This gives me an inconvertible types.
Enum.valueOf will do it, but it is pretty picky about it's type. Make sure you cast the Class to Class<? extends Enum>. Example:
enum Foo {
BLAT,
BLARG
};
System.out.println(Enum.valueOf((Class<? extends Enum>)Class.forName("Foo"), "BLARG"));
Have a look at Enum.valueOf( Class enumType,
String name ).
You are looking for MyClass.MyEnum.valueOf(enumString). No need to fully qualify the class in the string.
Related
An example of this is:
SBHttpRequest<D extends SBHttpDeserializer<?>, RBT> : this compiles fine but the type is not bounded for the response class
SBHttpRequest<D extends SBHttpDeserializer<RT>, RBT> : This does not compile: RT cannot resolved to a type
I also tried SBHttpRequest<D<RT> extends SBHttpDeserializer<RT>, RBT>: which it tells me
the < > are in the wrong spots
D is the deserializer class which extends SBHttpDesrializer
RT is the response type or the type the deserializer changes the response into
RBT is the request body type (always a byte[] in this instance)
I would like to use the response type for bounding some conditions in the class and clear some raw type compiler warnings.
Either add a generic type parameter for the return type, or create a class/interface when your want to lock down the type:
class ByteArraySBHttpDeserializer implements SBHttpDeserializer<byte[]> {}
Then:
SBHttpRequest< ByteArraySBHttpDeserializer, RBT>
It’s a bit clunky, but so is generics.
I ended up going with Turing85's idea.
Just include the type
Despite sonarlint's complaint about generic names being larger than 1 character:
public class SBHttpRequest<RESPONSE_TYPE, DESRERIALIZER_TYPE extends SBHttpDeserializer<RESPONSE_TYPE>, REQUEST_BODY_TYPE>
I have a class I am obtaining by using Class.forName like this
Class<?> processClass = Class.forName(entity.getClassname());
I need to know if processClass is an instance of this type
(Class<? extends Job>)
How can I check this in Java? I mean I need to do something like this:
if (processClass.isAssignableFrom((Class<? extends Job>))){
....
}
How can that be achieved in Java?
I assume you want to test
Job.class.isAssignableFrom(processClass)
I have the following setup of classes/interfaces.
Interface IFoobar
Class BaseClass which implements IFoobar and is abstract
Class ConcreteClassA which extends BaseClass
Class ConcreteClassB which extends BaseClass
Class ConcreteClassC which extends BaseClass
I have a method for which I need to pass instances of java.lang.Class for the above concrete classes. I am declaring it like so.
void doSomething(String id, Class<IFoobar> c)
However, when I try to compile, java complains with an error more or less like this:
doSomething(java.lang.String,java.lang.Class<IFoobar>) in javaclass cannot be applied to
(java.lang.String,java.lang.Class<ConcreteClassA>)
register("12345", ConcreteClassA.class);
^
1 error
I've only recently needed to use java.lang.Class to do things, so I am guessing I am missing something simple. I would have expected the typed class declaration to work like normal parameters in that the concrete classes are recognized as instances of the interface, but this apparently isn't the case.
I've tried various methods of casting, etc and either not had the desired results, or had code which isn't valid. So any ideas as to what I need to do would be appreciated.
Thanks in advance.
A variable of type Class<IFoobar> can only hold a reference to a Class<IFoobar> object, not a Class<ConcreteClassA> object.
Change Class<IFoobar> to Class<? extends IFoobar>.
This behaviour is not particularly sensible for Class objects. It is much more logical for collections, where it stops you doing this:
void method1(List<IFoobar> list)
{
list.add(new ConcreteClassA());
}
void method2()
{
List<ConcreteClassB> list = /* something */;
method1(list);
// oops! we put a ConcreteClassA inside a List<ConcreteClassB>
}
the only accepted value for Class<IFoobar> is IFooBar.class. If you want to accept IFooBar.class and all its subclasses, you should use Class<? extends IFooBar>
The error has nothing to do with "Class"
Simply if you use
ArrayList<Object> x = new ArrayList<String>();
You get error: incompatible types
because, though the String class is a subclass of Object, ArrayList<Object> is a different type than ArrayList<String>. That is the nature of Generics.
You can use
void doSomething(String id, Class c)
I got the following class:
public class Repository<T> extends ExternalRepository<Wrapper<T>>
{
public Repository(Class<Wrapper<T>> type, DB db)
{
super(type, db);
}
}
But I have no idea how to call the construtor since
new Repository(Wrapper<SomeClass>.class, dbInstance)
does not work. So what can I do? I can change the Repository class if necessary.
You can't get the class instance for Wrapper<SomeClass> directly using .class literal. It is not allowed. You can only use it with raw type - Wrapper.class, or unbounded wildcard types - Wrapper<?>.class.
To get what you want, you've to use some type-casting here:
new Repository<SomeClass>((Class<Wrapper<SomeClass>>)(Class<?>)Wrapper.class,
dbInstance)
This first cast a Class<Wrapper> to a Class<?>, which is an unbounded wildcard reference. And then that reference can be type-casted to Class<Wrapper<SomeClass>>.
Also, don't forget to give the type argument while creating an instance of your generic class.
Here's what you need:
new Repository(Wrapper.class, dbInstance);
There's only one class descriptor for each generic class, including Wrapper.
I'm using Hibernate validator and trying to create a little util class:
public class DataRecordValidator<T> {
public void validate(Class<T> clazz, T validateMe) {
ClassValidator<T> validator = new ClassValidator<T>(clazz);
InvalidValue[] errors = validator.getInvalidValues(validateMe);
[...]
}
}
Question is, why do I need to supply the Class<T> clazz parameter when executing new ClassValidator<T>(clazz)? Why can't you specify:
T as in ClassValidator<T>(T)?
validateMe.getClass() as in ClassValidator<T>(validateMe.getClass())
I get errors when I try to do both options.
Edit: I understand why #1 doesn't work. But I don't get why #2 doesn't work. I currently get this error with #2:
cannot find symbol
symbol : constructor ClassValidator(java.lang.Class<capture#279 of ? extends java.lang.Object>)
location: class org.hibernate.validator.ClassValidator<T>
Note: Hibernate API method is (here)
Because T is not a value - it's just a hint for the compiler. The JVM has no clue of the T. You can use generics only as a type for the purposes of type checking at compile time.
If the validate method is yours, then you can safely skip the Class atribute.
public void validate(T validateMe) {
ClassValidator<T> validator =
new ClassValidator<T>((Class<T>) validateMe.getClass());
...
}
But the ClassValidator constructor requires a Class argument.
Using an unsafe cast is not preferred, but in this case it is actually safe if you don't have something like this:
class A {..}
class B extends A {..}
new DataRecordValidator<A>.validate(new B());
If you think you will need to do something like that, include the Class argument in the method. Otherwise you may be getting ClassCastException at runtime, but this is easily debuggable, although it's not quite the idea behind generics.
Because ClassValidator is requiring a Class object as its parameter, NOT an instance of the class in question. Bear in mind you might be able to do what you're trying to do with this code:
ClassValidator<? extends T> validator = new ClassValidator<? extends T>(validateMe.getClass());