1 Reply Latest reply on Jul 29, 2011 5:52 PM by jtahlborn

    Generic & Unsafe/Unchecked operations.

      Hi everybody,

      I seem to be misunderstanding some of the principles of generics I think.
      Assume you have the following interface definition:
      public interface IPersistentBeanManager<T extends PersistentBean>{
          public T findById(Long id, Class<T> clazz) throws InvalidParameterException, EntityDoesNotExistException, StorageException;
      The interface above is implemented by a base class that provides a default implementation for the declaration above:
      public abstract class AbstractPersistentBeanManager<T extends PersistentBean> implements IPersistentBeanManager{
          public T findById(Long id, Class clazz) throws InvalidParameterException, EntityDoesNotExistException, StorageException {
              ParameterValidation.objectNotNull(id, "findById", "id", getLogger());
                  T theBean = (T)getEntityManager().find(clazz, id);
                  if(theBean == null){
                      getLogger().warn("the specified bean does not exist : id = " + id.longValue());
                      throw new EntityDoesNotExistException("findById", "the specified bean does not exist : id = " + id.longValue());
                  return theBean;
              }catch(RuntimeException ex){
                  getLogger().fatal("the request could not be processed, reason = " + ex.getMessage());
                  throw new StorageException("findById", "the request could not be processed", ex);
          protected abstract EntityManager getEntityManager();
          protected abstract Logger getLogger();
      Now I have three questions for the code above:
      1. Why doesn't the implementation of the abstract class allow Class<T> clazz in its arguments? I would the signature of the implementing class be the same as the interface...

      2. Why does compilation complain about unsafe of uncheck operations for the findById-method?
      The compiler gives 3 warnings for this code :
      warning: [unchecked] unchecked conversion
      found : java.lang.Class
      required: java.lang.Class<T>
      > T theBean = (T)getEntityManager().find(clazz, id);
      warning: [unchecked] unchecked method invocation: <T>find(java.lang.Class<T>,java.lang.Object) in javax.persistence.EntityManager is applied to (java.lang.Class,java.lang.Long)
      T theBean = (T)getEntityManager().find(clazz, id);
      warning: [unchecked] unchecked cast
      found : java.lang.Object
      required: T
      T theBean = (T)getEntityManager().find(clazz, id);
      3. If I am correct, generics is nothing more than a way to inform the compiler about the type to expect at runtime. Runtime is no longer aware of the fact that generics are being used in the code. Is this correct? So there is no way to know what the actual type of T is at runtime except by passing the actual class as a parameter value in the method as stated above. There is no T.getClass() like construct that returns the runtime type of the class, which is in this case is known to be a subclass of PersistentBean.

      Thanks in advance for clearing things out a bit more!

      Kind regards,