private List gridModel;
public List getGridModel() {
return gridModel;
}
Eclipse shows a warning:
List is a raw type. References to generic type List should be parameterized.
Changing the code to below will remove the warning
private List<?> gridModel;
public List<?> getGridModel() {
return gridModel;
}
However the above code shows a Major pitfall error in SonarQube which says:
Remove usage of generic wildcard type. Generic wildcard types should not be used in return parameters
So how can I fix this warning?
I see a similar question here but could not find the solution .
Using Class<? extends Object>
did not remove Sonar warning.
Using a wildcard as a return type should be avoided because it forces programmers using the code to deal with wildcards. A list defined by List<? extends ...> can be informally thought of as read-only, but that is not a strict guarantee.
Guidelines for Wildcards. Upper bound wildcard − If a variable is of in category, use extends keyword with wildcard. Lower bound wildcard − If a variable is of out category, use super keyword with wildcard. Unbounded wildcard − If a variable can be accessed using Object class method then use an unbound wildcard.
It is highly recommended not to use wildcard types as return types. Because the type inference rules are fairly complex it is unlikely the user of that API will know how to use it correctly. Let's take the example of method returning a "List<? extends Animal>".
In generic code, the question mark (?), called the wildcard, represents an unknown type. The wildcard can be used in a variety of situations: as the type of a parameter, field, or local variable; sometimes as a return type (though it is better programming practice to be more specific).
So how can I fix this warning ?
You can use a type parameter for your class :
public class GridModelHolder<T> {
private List<T> gridModel;
public List<T> getGridModel() {
return gridModel;
}
}
The client code can then decide what type of List
GridModelHolder
holds :
GridModelHolder<String> gridModelHolder = new GridModelHolder<String>(new ArrayList<String>);
However, if you insist on using raw types, you can either suppress the warnings or simply have a List of objects (Neither of these are recommended)
@SuppressWarnings("unchecked")
public class GridModelHolder {
private List gridModel;
public List getGridModel() {
return gridModel;
}
}
OR
public class GridModelHolder {
private List<Object> gridModel;
public List<Object> getGridModel() {
return gridModel;
}
}
Make the class take a generic. Apply that generic to the List
. Also, the warning is valid (a collection type without a generic is a raw type). Something like,
class MyClass<T> {
private List<T> gridModel;
public List<T> getGridModel() {
return gridModel;
}
}
If you really want to disable the type-checking then make the List
generic on Object
(which is what a raw type is) like
private List<Object> gridModel;
public List<Object> getGridModel() {
return gridModel;
}
I'm sorry, that doesn't make sense; there's nothing wrong with returning Foo<?>
if the API needs to. Even the Object
class has a
method
like that.
Here's the list of public methods in JDK that return with wildcards:
(There are more in javax
, but the list is too long to be posted on stackoverflow. See complete list )
java.awt.Font#getAttributes -> java.util.Map<java.awt.font.TextAttribute, ?>
java.awt.Toolkit#mapInputMethodHighlight -> java.util.Map<java.awt.font.TextAttribute, ?>
java.awt.datatransfer.DataFlavor#getDefaultRepresentationClass -> java.lang.Class<?>
java.awt.datatransfer.DataFlavor#getRepresentationClass -> java.lang.Class<?>
java.awt.im.InputMethodHighlight#getStyle -> java.util.Map<java.awt.font.TextAttribute, ?>
java.beans.BeanDescriptor#getBeanClass -> java.lang.Class<?>
java.beans.BeanDescriptor#getCustomizerClass -> java.lang.Class<?>
java.beans.EventSetDescriptor#getListenerType -> java.lang.Class<?>
java.beans.IndexedPropertyDescriptor#getIndexedPropertyType -> java.lang.Class<?>
java.beans.PropertyDescriptor#getPropertyEditorClass -> java.lang.Class<?>
java.beans.PropertyDescriptor#getPropertyType -> java.lang.Class<?>
java.io.ObjectStreamClass#forClass -> java.lang.Class<?>
java.io.ObjectStreamField#getType -> java.lang.Class<?>
java.lang.Class#asSubclass -> java.lang.Class<? extends U>
java.lang.Class#forName -> java.lang.Class<?>
java.lang.Class#getComponentType -> java.lang.Class<?>
java.lang.Class#getDeclaringClass -> java.lang.Class<?>
java.lang.Class#getEnclosingClass -> java.lang.Class<?>
java.lang.Class#getEnclosingConstructor -> java.lang.reflect.Constructor<?>
java.lang.Class#getSuperclass -> java.lang.Class<? super T>
java.lang.ClassLoader#loadClass -> java.lang.Class<?>
java.lang.EnumConstantNotPresentException#enumType -> java.lang.Class<? extends java.lang.Enum>
java.lang.Object#getClass -> java.lang.Class<?>
java.lang.annotation.Annotation#annotationType -> java.lang.Class<? extends java.lang.annotation.Annotation>
java.lang.annotation.IncompleteAnnotationException#annotationType -> java.lang.Class<? extends java.lang.annotation.Annotation>
java.lang.annotation.Repeatable#value -> java.lang.Class<? extends java.lang.annotation.Annotation>
java.lang.instrument.ClassDefinition#getDefinitionClass -> java.lang.Class<?>
java.lang.invoke.MethodHandleInfo#getDeclaringClass -> java.lang.Class<?>
java.lang.invoke.MethodHandleProxies#wrapperInstanceType -> java.lang.Class<?>
java.lang.invoke.MethodHandles$Lookup#lookupClass -> java.lang.Class<?>
java.lang.invoke.MethodType#parameterType -> java.lang.Class<?>
java.lang.invoke.MethodType#returnType -> java.lang.Class<?>
java.lang.ref.ReferenceQueue#poll -> java.lang.ref.Reference<? extends T>
java.lang.ref.ReferenceQueue#remove -> java.lang.ref.Reference<? extends T>
java.lang.reflect.Executable#getDeclaringClass -> java.lang.Class<?>
java.lang.reflect.Field#getDeclaringClass -> java.lang.Class<?>
java.lang.reflect.Field#getType -> java.lang.Class<?>
java.lang.reflect.Member#getDeclaringClass -> java.lang.Class<?>
java.lang.reflect.Method#getDeclaringClass -> java.lang.Class<?>
java.lang.reflect.Method#getReturnType -> java.lang.Class<?>
java.lang.reflect.Parameter#getType -> java.lang.Class<?>
java.lang.reflect.Proxy#getProxyClass -> java.lang.Class<?>
java.rmi.activation.ActivationDesc#getData -> java.rmi.MarshalledObject<?>
java.rmi.activation.ActivationGroupDesc#getData -> java.rmi.MarshalledObject<?>
java.rmi.activation.ActivationInstantiator#newInstance -> java.rmi.MarshalledObject<? extends java.rmi.Remote>
java.rmi.activation.Activator#activate -> java.rmi.MarshalledObject<? extends java.rmi.Remote>
java.rmi.server.LoaderHandler#loadClass -> java.lang.Class<?>
java.rmi.server.RMIClassLoader#loadClass -> java.lang.Class<?>
java.rmi.server.RMIClassLoader#loadProxyClass -> java.lang.Class<?>
java.rmi.server.RMIClassLoaderSpi#loadClass -> java.lang.Class<?>
java.rmi.server.RMIClassLoaderSpi#loadProxyClass -> java.lang.Class<?>
java.security.acl.Group#members -> java.util.Enumeration<? extends java.security.Principal>
java.security.cert.CertPath#getCertificates -> java.util.List<? extends java.security.cert.Certificate>
java.security.cert.CertStore#getCRLs -> java.util.Collection<? extends java.security.cert.CRL>
java.security.cert.CertStore#getCertificates -> java.util.Collection<? extends java.security.cert.Certificate>
java.security.cert.CertStoreSpi#engineGetCRLs -> java.util.Collection<? extends java.security.cert.CRL>
java.security.cert.CertStoreSpi#engineGetCertificates -> java.util.Collection<? extends java.security.cert.Certificate>
java.security.cert.CertificateFactory#generateCRLs -> java.util.Collection<? extends java.security.cert.CRL>
java.security.cert.CertificateFactory#generateCertificates -> java.util.Collection<? extends java.security.cert.Certificate>
java.security.cert.CertificateFactorySpi#engineGenerateCRLs -> java.util.Collection<? extends java.security.cert.CRL>
java.security.cert.CertificateFactorySpi#engineGenerateCertificates -> java.util.Collection<? extends java.security.cert.Certificate>
java.security.cert.CollectionCertStoreParameters#getCollection -> java.util.Collection<?>
java.security.cert.PolicyNode#getChildren -> java.util.Iterator<? extends java.security.cert.PolicyNode>
java.security.cert.PolicyNode#getPolicyQualifiers -> java.util.Set<? extends java.security.cert.PolicyQualifierInfo>
java.security.cert.X509CRL#getRevokedCertificates -> java.util.Set<? extends java.security.cert.X509CRLEntry>
java.time.chrono.ChronoLocalDate#atTime -> java.time.chrono.ChronoLocalDateTime<?>
java.time.chrono.ChronoLocalDateTime#from -> java.time.chrono.ChronoLocalDateTime<?>
java.time.chrono.ChronoZonedDateTime#from -> java.time.chrono.ChronoZonedDateTime<?>
java.time.chrono.Chronology#localDateTime -> java.time.chrono.ChronoLocalDateTime<? extends java.time.chrono.ChronoLocalDate>
java.time.chrono.Chronology#zonedDateTime -> java.time.chrono.ChronoZonedDateTime<? extends java.time.chrono.ChronoLocalDate>
java.util.IllegalFormatConversionException#getArgumentClass -> java.lang.Class<?>
java.util.PriorityQueue#comparator -> java.util.Comparator<? super E>
java.util.Properties#propertyNames -> java.util.Enumeration<?>
java.util.SortedMap#comparator -> java.util.Comparator<? super K>
java.util.SortedSet#comparator -> java.util.Comparator<? super E>
java.util.Spliterator#getComparator -> java.util.Comparator<? super T>
java.util.TreeMap#comparator -> java.util.Comparator<? super K>
java.util.TreeSet#comparator -> java.util.Comparator<? super E>
java.util.concurrent.AbstractExecutorService#submit -> java.util.concurrent.Future<?>
java.util.concurrent.ConcurrentSkipListMap#comparator -> java.util.Comparator<? super K>
java.util.concurrent.ConcurrentSkipListSet#comparator -> java.util.Comparator<? super E>
java.util.concurrent.CountedCompleter#firstComplete -> java.util.concurrent.CountedCompleter<?>
java.util.concurrent.CountedCompleter#getCompleter -> java.util.concurrent.CountedCompleter<?>
java.util.concurrent.CountedCompleter#getRoot -> java.util.concurrent.CountedCompleter<?>
java.util.concurrent.CountedCompleter#nextComplete -> java.util.concurrent.CountedCompleter<?>
java.util.concurrent.ExecutorService#submit -> java.util.concurrent.Future<?>
java.util.concurrent.ForkJoinPool#submit -> java.util.concurrent.ForkJoinTask<?>
java.util.concurrent.ForkJoinTask#adapt -> java.util.concurrent.ForkJoinTask<?>
java.util.concurrent.PriorityBlockingQueue#comparator -> java.util.Comparator<? super E>
java.util.concurrent.ScheduledExecutorService#schedule -> java.util.concurrent.ScheduledFuture<?>
java.util.concurrent.ScheduledExecutorService#scheduleAtFixedRate -> java.util.concurrent.ScheduledFuture<?>
java.util.concurrent.ScheduledExecutorService#scheduleWithFixedDelay -> java.util.concurrent.ScheduledFuture<?>
java.util.concurrent.ScheduledThreadPoolExecutor#schedule -> java.util.concurrent.ScheduledFuture<?>
java.util.concurrent.ScheduledThreadPoolExecutor#scheduleAtFixedRate -> java.util.concurrent.ScheduledFuture<?>
java.util.concurrent.ScheduledThreadPoolExecutor#scheduleWithFixedDelay -> java.util.concurrent.ScheduledFuture<?>
java.util.concurrent.ScheduledThreadPoolExecutor#submit -> java.util.concurrent.Future<?>
java.util.stream.Collectors#averagingDouble -> java.util.stream.Collector<T, ?, java.lang.Double>
java.util.stream.Collectors#averagingInt -> java.util.stream.Collector<T, ?, java.lang.Double>
java.util.stream.Collectors#averagingLong -> java.util.stream.Collector<T, ?, java.lang.Double>
java.util.stream.Collectors#counting -> java.util.stream.Collector<T, ?, java.lang.Long>
java.util.stream.Collectors#groupingBy -> java.util.stream.Collector<T, ?, M>
java.util.stream.Collectors#groupingBy -> java.util.stream.Collector<T, ?, java.util.Map<K, D>>
java.util.stream.Collectors#groupingBy -> java.util.stream.Collector<T, ?, java.util.Map<K, java.util.List<T>>>
java.util.stream.Collectors#groupingByConcurrent -> java.util.stream.Collector<T, ?, M>
java.util.stream.Collectors#groupingByConcurrent -> java.util.stream.Collector<T, ?, java.util.concurrent.ConcurrentMap<K, D>>
java.util.stream.Collectors#groupingByConcurrent -> java.util.stream.Collector<T, ?, java.util.concurrent.ConcurrentMap<K, java.util.List<T>>>
java.util.stream.Collectors#joining -> java.util.stream.Collector<java.lang.CharSequence, ?, java.lang.String>
java.util.stream.Collectors#mapping -> java.util.stream.Collector<T, ?, R>
java.util.stream.Collectors#maxBy -> java.util.stream.Collector<T, ?, java.util.Optional<T>>
java.util.stream.Collectors#minBy -> java.util.stream.Collector<T, ?, java.util.Optional<T>>
java.util.stream.Collectors#partitioningBy -> java.util.stream.Collector<T, ?, java.util.Map<java.lang.Boolean, D>>
java.util.stream.Collectors#partitioningBy -> java.util.stream.Collector<T, ?, java.util.Map<java.lang.Boolean, java.util.List<T>>>
java.util.stream.Collectors#reducing -> java.util.stream.Collector<T, ?, T>
java.util.stream.Collectors#reducing -> java.util.stream.Collector<T, ?, U>
java.util.stream.Collectors#reducing -> java.util.stream.Collector<T, ?, java.util.Optional<T>>
java.util.stream.Collectors#summarizingDouble -> java.util.stream.Collector<T, ?, java.util.DoubleSummaryStatistics>
java.util.stream.Collectors#summarizingInt -> java.util.stream.Collector<T, ?, java.util.IntSummaryStatistics>
java.util.stream.Collectors#summarizingLong -> java.util.stream.Collector<T, ?, java.util.LongSummaryStatistics>
java.util.stream.Collectors#summingDouble -> java.util.stream.Collector<T, ?, java.lang.Double>
java.util.stream.Collectors#summingInt -> java.util.stream.Collector<T, ?, java.lang.Integer>
java.util.stream.Collectors#summingLong -> java.util.stream.Collector<T, ?, java.lang.Long>
java.util.stream.Collectors#toCollection -> java.util.stream.Collector<T, ?, C>
java.util.stream.Collectors#toConcurrentMap -> java.util.stream.Collector<T, ?, M>
java.util.stream.Collectors#toConcurrentMap -> java.util.stream.Collector<T, ?, java.util.concurrent.ConcurrentMap<K, U>>
java.util.stream.Collectors#toList -> java.util.stream.Collector<T, ?, java.util.List<T>>
java.util.stream.Collectors#toMap -> java.util.stream.Collector<T, ?, M>
java.util.stream.Collectors#toMap -> java.util.stream.Collector<T, ?, java.util.Map<K, U>>
java.util.stream.Collectors#toSet -> java.util.stream.Collector<T, ?, java.util.Set<T>>
java.util.zip.ZipFile#entries -> java.util.Enumeration<? extends java.util.zip.ZipEntry>
java.util.zip.ZipFile#stream -> java.util.stream.Stream<? extends java.util.zip.ZipEntry>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With