Can I create an instance of a generic class without knowing its type parameter? I have only 'class' type, which have been obtained from the Class.forName (classname);
//generic class
public class MappedField<T> extends Field {
private T value;
private String sourceName;
public MappedField(String name, String sourceName, FieldType type){
super(name, type);
this.sourceName = sourceName;
}
public MappedField(String name, String sourceName, FieldType type, boolean key){
super(name, type, key);
this.sourceName = sourceName;
}
}
//here's my situation
String columnName = field.getSourceName() != null ? field.getSourceName() : field.getName();
Class c = Class.forName(field.getType().getFullClassName());
//I need like that if `field.getType() = "Integer"`: `MappedField<Integer> objField = new MappedField<Integer>(field)`;
MappedField objField = new MappedField(field);
objField.setValue(getField(c, rset, columnName));
object.getValues().add(objField);
EDIT:
It's like I have "java.lang.Integer" and want get MappedField
The Generic type will erased from the classes and interfaces on successful compilation.On runtime it is not possible to detect the generic type.
Refer the link:
Use reflection to create a generic parameterized class in Java
Related
I have a java class Jistthat has two fields, public final Object type and public Object[] content. In the constructor for Jist I want to take in an Object and get its type, then initialize content with some number of empty slots of that type. This is one of the several solutions that I have tried, and the error that I am currently receiving is in the actual initialization of the array:
public class Jist{
public final Object type;
public Object[] content;
public Jist(Object type){
this.type = type.getClass();
class myType extends Jist{
Class c = super.type.getClass();
public Class getType(){
return c;
}
};
content = new myType.getType()[4];
}
}
Make Jist generic on some type T. Pass the Class<T> in the constructor. Use Array.newInstance(Class<?>, int) like
public class Jist<T> {
public final Class<T> type;
public T[] content;
public Jist(Class<T> cls) {
this.type = cls;
content = (T[]) Array.newInstance(type, 4);
}
}
Yes, you can create new array instance using type Class.
Class<?> myTypeClass = myType.getType();
int arraySize = 10;
Object array = Array.newInstance(myTypeClass, arraySize);
https://docs.oracle.com/javase/tutorial/reflect/special/arrayInstance.html
I am constructing my POJO directly from the received JSON using Jackson's ObjectMapper. For that purpose I annotate my fields (in this case fields are abstract methods because I'm using AutoValue to reduce boilerplate) with #JsonProperty annotations.
Now, some of the fields in my POJO are enums, where JSON obviously contains a regular string. I would like to somehow validate that those JSON fields do indeed submit to the given enum type before the object is constructed.
Here is the example.
#JsonProperty(value = "messageType")
public abstract Optional<MessageType> messageType();
This property is of type enum MessageType, and the corresponding JSON field is ie. "messageType": "A_1" which is a string.
Now, if the "messageType" is something like "blabla" I'd like the validation to fail.
Is there any way to validate that with annotations using Hibernate Validator?
#JsonProperty(value = "messageType")
public abstract Optional messageType();
Assumed you have, MessageType as enum with distinct values A_1, A_2...
Create a static utility method to serialize/deserialize for the enum values from the received/sent json values
public static <T extends Enum<T>> T getEnumFromJson(Class<T> enumClass, String value)
{
if(enumClass == null) throw new IllegalArgumentException("EnumClass value can't be null");
for(Enum<?> enumValue : enumClass.getEnumConstants()){
if(enumValue.toString().equalsIgnoreCase(value)){
return (T) enumValue;
}
}
//Validation message construct to give more meaningful details to end-user
StringBuilder erroMsg = new StringBuilder();
boolean bFirst = true;
for(Enum<?> enumValue : enumClass.getEnumConstants()) {
errorMessage.append(bFirst ? "": ", ").append(enumValue);
bFirst = false;
}
throw new IllegalArgumentException(value + " is invalid value, Supported value are "+ errorMessage);
}
//Enum as represented below
public enum MessageType {
A_1,
A_2,
A_3
#JsonCreator
public static MessageType fromValue(String value){
return getEnumFromJson(MessageType.class, value);
}
#JsonValue
public String toJson(){
return name().toLowerCase();
}
}
I have the following class which represents a set of properties.
public class Properties
{
/** String type properties. */
private final List<String> m_stringProperties = Arrays.asList("str1", "str2", "str3");
/** Float type properties. */
private final List<String> m_floatProperties = Arrays.asList("float1", "float2", "float3");
/** Integer type properties. */
private final List<String> m_intProperties = Arrays.asList("int1", "int2");
public class PropertyType
{
private final String m_name;
private final Object m_value;
public PropertyType(String name, Object value)
{
m_name = name;
m_value = value;
}
public String getName()
{
return m_name;
}
public Object getValue()
{
return m_value;
}
}
/** The container for the properties. */
private final Map<String, PropertyType> m_properties = new HashMap<>();
public PropertyType getProperty(String name)
{
return m_properties.get(name);
}
public void setProperty(String name, Object value)
{
if ((m_stringProperties.contains(name) && value instanceof String)
|| (m_floatProperties.contains(name) && value instanceof Float)
|| (m_intProperties.contains(name) && value instanceof Integer))
{
m_properties.put(name, new PropertyType(name, value));
}
else
{
assert false : "Invalid property name";
}
}
}
Notes
Each property has a name and a value.
Property values can be of type String, Float or Integer.
The names of properties is restricted to the values defined in the list at the top of the class.
A given property can only be added to the map if it is the correct type for that property name.
The class could be used as follows:
Properties properties = new Properties();
// set properties
properties.setProperty("str1", "testId");
properties.setProperty("float1", 1.0f);
// get properties
Properties.PropertyType str1 = properties.getProperty("str1");
Properties.PropertyType float1 = properties.getProperty("float1");
Properties.PropertyType invalid = properties.getProperty("unknown"); // return null
System.out.println("str1: " + str1.getValue());
System.out.println("float1: " + float1.getValue());
float f1 = (float) properties.getProperty("float1").getValue();
Object o1 = properties.getProperty("float1").getValue();
System.out.println("f1: " + f1);
System.out.println("o1: " + o1);
properties.setProperty("str1", 1.0f); // assertion - str1 property should be String, not Float
I'd like to know if there is a better way to implement this. Specifically, I'd like to avoid the use of Object and the casting that goes with it. I've experimented with a parametrised class and generic types and even a typesafe heterogenous container as described in Item 20 of Effective Java.
I would like to make it as typesafe as possible - i.e. enforce type checking by the compiler - so that if getProperty is called the return value is automatically the correct type.
I realise that I could overload setProperty for each type and that getProperty could just return an Object instead of the nested type PropertyType but that would still leave me with a container of <String, Object>.
I'm a Java newbie coming from C++. In C++ the map value would be a boost::variant.
To make sure that the class will receive one of the 3 types, and the Compiler will acuse that, you can use some Polymorphism.
Example:
public PropertyType(String name, String value)
{
m_name = name;
m_value = value;
}
public PropertyType(String name, Integer value)
{
m_name = name;
m_value = value;
}
public PropertyType(String name, Float value)
{
m_name = name;
m_value = value;
}
The String,Integer and Float extends Object, so you don't need to cast they to the variable private final Object m_value;
But if you need to check the type of the variable in execution type (For example, create and variable and don't know if it's some of the three types) this may not work.
I speak Spanish, use the translator to ask this question, Sorry for the spelling.
Also, do not be like asking exactly what I want to do.
I want to create a list of an object passing through parameter.
public void createListUnknown(? Class myClass? or ? Object myObject?) {
List<myClass> my_list;
//or
List<myObject> my_list;
}
example use:
public class Model{
public String name;
public String age;
}
as it should be?
createListUnknown(?? MyModel ??)
Basically I want to create a list with an object that comes parameter to a function
An example where you want to apply is the following:
//final GsonModelUsuariosLoginGet gsonModelUsuariosLoginGet
//= gson.fromJson(responseData, GsonModelUsuariosLoginGet.class);
return gson.fromJson(responseData, httpObject.getObjectGet().getClass());
and
Object aClass = httpObject.getObjectGet().getClass();
List< httpObject.getObjectGetClass() > aClasses;
Type collectionType = new TypeToken<List<aClass>>(){}.getType();
final List<GsonModelArticulos> articulos = gson.fromJson(responseData, collectionType);
create list
public <T> List<T> makeList(Class<T> type) {
return new ArrayList<T>();
}
get type list
Using the Type interface.
private <T> Type getType(Class<T> type) {
Type typeOfObjectsListNew = new TypeToken<ArrayList<T>>() {}.getType();
return typeOfObjectsListNew;
}
I have a factory, and I want to restrict the possible values that may be passed into the get method.
public static class FooFactory{
public static final String TYPE1= "type1";
public static Foo getFoo(String type){
switch(type){
case "type1":
return new Type1();
}
}
}
To use this:
FooFactory.getFoo(FooFactory.TYPE1);
I'd like to restrict the parameters that may be passed in. Is an idea to make a Type abstract class, then subclass and use Type as the parameter?
Don't subclass it, just create a Type class with a private constructor that takes a stirng parameter, and define public Type constants.
Something like this.
public final class Type {
public static final Type FOO = new Type( "foo" );
public static final Type BAR = new Type( "bar" );
private String type;
private Type( String type ) {
this.type = type;
}
public String getType() { return type; }
}