Reputation: 4709
This question is not the same as Eclipse warning - Class is a raw type. References to generic type Class<T> should be parameterized. Only the generated warning is the same.
The code below results in the warning:
X.PropertyType is a raw type. References to generic type X.PropertyType should be parameterized.
at the lines indicated when built using Eclipse. One quick fix offered by Eclipse is to add @SuppressWarnings("unchecked")
but I don't want to do that without fully understanding the implications, which at the moment I don't.
How can I eliminate the warning without suppressing it? I've seen other questions on SO related to this warning but I think I need an answer specific to the code below to understand the issue.
import java.util.HashMap;
import java.util.Map;
public class X
{
// *** WARNING ***
private final Map<String, PropertyType> m_properties = new HashMap<String, PropertyType>();
public class PropertyType<T>
{
private final String m_name;
private final T m_value;
private final Class<T> m_type;
public PropertyType(String name, T value, Class<T> type)
{
m_name = name;
m_value = value;
m_type = type;
}
public String getName() { return m_name; }
public T getValue() { return m_value; }
public Class<T> getType() { return m_type; }
}
public <U> void setProperty(String name, U value)
{
// *** WARNING ***
m_properties.put(name, new PropertyType(name, value, String.class));
}
}
Also, in the method setProperty
, I would like to pass the type of value
when creating an instance of PropertyType
. I'm just passing a String
type at the moment. What is the best way to do that?
I could modify setProperty
as follows:
public <U> void setProperty(String name, U value, Class<U> type)
but I've been looking for a better way.
Upvotes: 1
Views: 15441
Reputation: 1074178
Here, you're using a raw PropertyType
type:
private final Map<String, PropertyType> m_properties = new HashMap<String, PropertyType>();
// -----------------------^^^^^^^^^^^^^
...but you've declared PropertyType
as a parameterized type, so naturally the compiler and IDE warn you that you're doing the parameterized-to-raw thing, which usually indicates a bug.
Normally I'd say you need to parameterize it:
private final Map<String, PropertyType<T>> m_properties = new HashMap<String, PropertyType>();
// -----------------------------------^^^
...but you've said you don't want to parameterize X
, the containing class.
You either need to parameterize X
, or make PropertyType
a raw type. Consider this method:
public <U> void setProperty(String name, U value)
m_properties.put(name, new PropertyType(name, value, String.class));
}
It can be called with any U
type, but your m_properties
can only be created with a single T
(or be raw).
Based on X, you don't want PropertyType
to be parameterized. Or you want X
to be (in which case you drop <U>
from the setProperty
declaration). That's basically the choice.
Upvotes: 2
Reputation: 1918
You can use a wildCard to workaround the warning at the HashMap declaration. E.g.
HashMap<String, PropertyType<?>> map; //declare
Or pass in the final genericType if possible.
For the second problem, you can use
value.getClass();
To get its classType, and use that as identifier at the same time. (Might improve performance on the HashMap operations if the classObject is used as key instead of a String, though its micro optimization)
Upvotes: 2
Reputation: 140427
What you are asking for probably doesn't work as you want it to.
You could have something like:
public class X<T> {
private final Map<String, PropertyType<T>> m_properties = new HashMap<>();
Meaning: there is no way to use generics to allow for different kinds of PropertyType<T>
objects within your Map ... and still have the compiler be checking those types. That is simply not possible.
And hint: read about java coding style guidelines. "Hungarian" notation together with "_" for variables names; bad style that is.
Upvotes: 0
Reputation: 8339
You will need to pass a Type while declaring your hashmap like example below:
private final Map<String, PropertyType<String>> m_properties = new HashMap<String, PropertyType<String>>();
Because it is class level parameter
Upvotes: 0