简体   繁体   中英

Warning - Class is a raw type. References to generic type Class<T> should be parameterized

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.

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.

You can use a wildCard to workaround the warning at the HashMap declaration. Eg

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)

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM