Generic Method override compatibility

I tried to find references to the problem but couldn't. I face it all the time and I thought some else must have had the same problem already.
Oh well, here it goes.
With both 3.1M4 and 3.1M5a the following code compiles without any problems.
public interface MyIface {
    public <T> void foo(T p);
public class MyClass implements MyIface{
    public <T extends Integer> void foo(T p) {
         //does something
}However, javac 1.5 gives me:
MyClass.java:1: MyClass is not abstract and does not override abstract method <T>foo(T) in MyIface
public class MyClass implements MyIface{
^
1 error
I found many different variations to this problem, which I am not going to list here as I am trying to be concise. But for the eclipse compiler, <T extends Integer> is the same as <T> in terms of method signature. For the javac compiler these are different thingss.
Does anyone know if this is a Bug in eclipse or javac, or if this is a known decision, which is taking both tools in different directions?
Coconha

Coco, you have to understand how generics work in the compiler to understand this. Basically, erasure means that all the fancy generics stuff you write in your source code gets 'erased' when it gets compiled... So:public interface MyIface {
    public <T> void foo(T p);
}gets compiled and the resulting .class file, if you decompiled it, would actually look like this:public interface MyIface {
    public void foo(Object p); // NOTICE that "T" gets erased to plain old java.lang.Object
}See? The same thing happens with MyClass:public class MyClass implements MyIface {
    public <T extends Integer> void foo(T p) {
         //does something
}after it's compiled, actually looks like this inside the .class file:public class MyClass implements MyIface {
    public void foo(Integer p) { // NOTICE that "T extends Integer" gets erased to plain old Integer!
         //does something
}Do you see what the problem is now? MyClass has a method called foo(Integer) and MyIface has a method called foo(Object). Obviously now, you see, foo(Integer) shouldn't override foo(Object). The Eclipse compiler should actually complain that you haven't implemented foo(Object) in MyClass. Do you follow?
Let's look at your second example.public class Base {
  public <S> void foo(S a) {
    System.out.println("Base: " + a);
public class Sub extends Base {
  public <S extends Integer> void foo(S a) {
    super.foo(a); // should be an error here! super.foo(Integer) doesn't exist!
    System.out.println("Sub: " + a);
}Let's apply erasure manually and see why there is no error:public class Base {
  public void foo(Object a) {
    System.out.println("Base: " + a);
public class Sub extends Base {
  public void foo(Integer a) {
    super.foo(a); // calls foo(Object a)! you could also write "this.foo((Object)a)"
    System.out.println("Sub: " + a);
}Sub actually has two methods - foo(Integer a) which it defines explicitly - and foo(Object a) which it inherits from Base.

Similar Messages

  • What is the advantages of polymorphism over method overriding?

    what is the advantages of polymorphism over method overriding,that means if we are able to to create object at different instances at diff time for that sub class reff variable than what is the need of careating object of super class data type(i.e why always it is necessary to have upcasting for polymorphism?but if we can achive the same output without upcasting).....please tell me..lets have complete discuss..

    Seriously though....
    WebLogic (for which I have deployed many apps on) as
    well as Websphere are both high end Java application
    servers, meaning J2EE servers (in short). They allow
    one to deploy Enterprise Archive(EAR), a Web
    Archive(WAR), or an EJB Archive (in a JR file).
    These two servers allow one to deploy EJBs, use
    e JNDI, JMS, connectors, and other J2EE technologies
    - Tomcat does not. well, EJBs - no
    JNDI, yes - http://tomcat.apache.org/tomcat-4.1-doc/jndi-resources-howto.html
    JMS - yes (with an implementation, such as ActiveMQ: http://activemq.codehaus.org/Tomcat)
    Not sure what you mean by "connectors".
    Tomcat provides quite a bit of functionality (but yes, no EJBs)

  • How to create a generic method?

    Hi,
      I am using a std task TS01200205 to create instance for a BOR object. There are 2 key fields. I want to pass these 2 to the ObjectKey field.
    As for as I know, we have to concatenate these two Keyfields and assign it to 'Object Key' parameter.
      How can I concatenate the 2 strings in my Workflow? Is there any std way of doing it?
    Also what is a generic method? How to create it? Can I make use of generic method to achieve this?
    Thanks,
    Sivagami

    If you want to use it in different workflows the best solution is probably to define an interface and define and implement the method there (a nice thing about BOR interfaces is that you can provide an implementation and not just the definition).
    All you then need to do is let your object type(s) implement that interface, which only requires adding the interface since the implementation has been done already.
    However, I am not saying this is a good way of approaching things, I'm just telling you how you can implement what you suggest.

  • [ABAP OO] Generic method get lines

    Hi Experts,
    I am creating a generic method to get the numbers of lines from any table, like below:
    TABNAME type string.
    LINES type i.
    METHOD get_lines_from_any_dbtab.
      DATA lo_tab TYPE REF TO data  .
      CREATE DATA  lo_tab  TYPE TABLE OF (tabname) .
      SELECT *  FROM (tabname)  INTO TABLE lo_tab .
      DESCRIBE TABLE lo_tab LINES lines  .
      CONDENSE lines 
    METHOD.
    I have an error message during the compilation as:
    LO_TAB is not an internal table.
    Any idea ?
    Kind regards.
    Rachid.

    Got it:
      DATA lo_tab TYPE REF TO data  .
      FIELD-SYMBOLS <fs_dbtab>  TYPE ANY TABLE  .
      CREATE DATA  lo_tab  TYPE TABLE OF (tabname).
      ASSIGN lo_tab->* TO <fs_dbtab>  .
      SELECT *  FROM (tabname)  INTO TABLE <fs_dbtab>  .
      DESCRIBE TABLE <fs_dbtab> LINES lines  .
      CONDENSE lines  .

  • StartDrag using Generic method in Actionscript 3

    Hi,
    AS3:
    How to get general id (or) name from xml loaded images. bcoz, i want to drag and drop that images in generic method. Now, i currently used the event.target.name for each one.
    So, code length was too large. See my code below.
    /*********loading images through xml********/
    var bg_container_mc:MovieClip
    var bg_bg_myXMLLoader:URLLoader = new URLLoader();
    bg_bg_myXMLLoader.load(new URLRequest("xml/backgroundimages.xml"));
    bg_bg_myXMLLoader.addEventListener(Event.COMPLETE, processXML_bg);
    function processXML_bg(e:Event):void {
              var bg_myXML:XML=new XML(e.target.data);
              columns_bg=bg_myXML.@COLUMNS;
              bg_my_x=bg_myXML.@XPOSITION;
              bg_my_y=bg_myXML.@YPOSITION;
              bg_my_thumb_width=bg_myXML.@WIDTH;
              bg_my_thumb_height=bg_myXML.@HEIGHT;
              bg_my_images=bg_myXML.IMAGE;
              bg_my_total=bg_my_images.length();
              bg_container_mc = new MovieClip();
              bg_container_mc.x=bg_my_x;
              bg_container_mc.y=bg_my_y;
              ContentHead.addChild(bg_container_mc);
              for (var i:Number = 0; i < bg_my_total; i++) {
                       var bg_thumb_url=bg_my_images[i].@THUMB;
                        var bg_thumb_loader = new Loader();
                       bg_thumb_loader.load(new URLRequest(bg_thumb_url));
                       bg_thumb_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, thumbLoaded_bg);
                       bg_thumb_loader.name="bg_load"+i;
                       bg_thumb_loader.addEventListener(MouseEvent.MOUSE_DOWN, bg_down)
                       bg_thumb_loader.x = (bg_my_thumb_width-18)*bg_x_counter;
                       bg_thumb_loader.y = (bg_my_thumb_height-45)*bg_y_counter;
                       if (bg_x_counter+1<columns_bg) {
                                 bg_x_counter++;
                       } else {
                                 bg_x_counter=0;
                                 bg_y_counter++;
    function thumbLoaded_bg(e:Event):void {
              var my_thumb_bg:Loader=Loader(e.target.loader);
             var sprite:Sprite = new Sprite();
              var shape:Shape = new Shape();
              shape.graphics.lineStyle(1, 0x0098FF);
              shape.graphics.drawRect(e.target.loader.x-2, e.target.loader.y-2, e.target.loader.width+4, e.target.loader.height+4);
              sprite.addChild(shape);
              sprite.addChild(my_thumb_bg);
              sprite.x=4;
              bg_container_mc.addChild(sprite);
              my_thumb_bg.contentLoaderInfo.removeEventListener(Event.COMPLETE, thumbLoaded_bg);
    //  get name for each image. 
    I want to change this code in generic method. do needful.
    function bg_down(event:MouseEvent):void {
              var bg_name:String=new String(event.currentTarget.name);
              var bg_load:MovieClip=event.currentTarget as MovieClip;
              if (event.currentTarget.name=="bg_load0") {
                      var alaska_mc:alaska_png=new alaska_png();
                       addChild(alaska_mc);
                       alaska_mc.x=stage.mouseX;
                       alaska_mc.y=stage.mouseY;
                       alaska_mc.name="alaska_duplicate"+alaska_inc;
                       alaska_inc++;
                       alaska_mc.startDrag(false);
                      alaska_mc.addEventListener(MouseEvent.MOUSE_UP, stdrag);
                       alaska_mc.addEventListener(MouseEvent.MOUSE_UP, stdrag);
              if (event.currentTarget.name=="bg_load1") {
                       var lake_mc:lake_png=new lake_png();
                       addChild(lake_mc);
                       lake_mc.x=lake_mc.mouseX;
                       lake_mc.y=lake_mc.mouseY;
                       lake_mc.name="lake_duplicate"+lake_inc;
                       lake_inc++;
                       lake_mc.startDrag(false);
                       lake_mc.addEventListener(MouseEvent.MOUSE_UP, stdrag);
              if (event.currentTarget.name=="bg_load2") {
                       var mountn_mc:mountn_png=new mountn_png();
                       addChild(mountn_mc);
                       mountn_mc.x=mountn_mc.mouseX;
                       mountn_mc.y=mountn_mc.mouseY;
                       mountn_mc.name="mountn_duplicate"+mountn_inc;
                       mountn_inc++;
                       mountn_mc.startDrag(false);
                       mountn_mc.addEventListener(MouseEvent.MOUSE_UP, stdrag);
              if (event.currentTarget.name=="bg_load3") {
                       var town_mc:town_png=new town_png();
                       addChild(town_mc);
                       town_mc.x=town_mc.mouseX;
                       town_mc.y=town_mc.mouseY;
                       town_mc.name="town_duplicate"+town_inc;
                       town_inc++;
                       town_mc.startDrag(false);
                       town_mc.addEventListener(MouseEvent.MOUSE_UP, stdrag);
              if (event.currentTarget.name=="bg_load4") {
                       var water_mc:water_png=new water_png();
                       addChild(water_mc);
                       water_mc.x=water_mc.mouseX;
                       water_mc.y=water_mc.mouseY;
                       water_mc.name="water_duplicate"+water_inc;
                       water_inc++;
                       water_mc.startDrag(false);
                      water_mc.addEventListener(MouseEvent.MOUSE_UP, stdrag);
              if (event.currentTarget.name=="bg_load5") {
                       var city_mc:city_png=new city_png();
                       addChild(city_mc);
                       city_mc.x=city_mc.mouseX;
                       city_mc.y=city_mc.mouseY;
                       city_mc.name="city_duplicate"+city_inc;
                       city_inc++;
                       city_mc.startDrag(false);
                      city_mc.addEventListener(MouseEvent.MOUSE_UP, stdrag);
              if (event.currentTarget.name=="bg_load6") {
                        var citywide_mc:citywide_png=new citywide_png();
                       addChild(citywide_mc);
                       citywide_mc.x=citywide_mc.mouseX;
                       citywide_mc.y=citywide_mc.mouseY;
                       citywide_mc.name="citywide_duplicate"+citywide_inc;
                       citywide_inc++;
                       citywide_mc.startDrag(false);
                      citywide_mc.addEventListener(MouseEvent.MOUSE_UP, stdrag);
              if (event.currentTarget.name=="bg_load7") {
                       var downtown_mc:downtown_png=new downtown_png();
                       addChild(downtown_mc);
                       downtown_mc.x=downtown_mc.mouseX;
                       downtown_mc.y=downtown_mc.mouseY;
                       downtown_mc.name="downtown_duplicate"+downtown_inc;
                       downtown_inc++;
                       downtown_mc.startDrag(false);
                      downtown_mc.addEventListener(MouseEvent.MOUSE_UP, stdrag);
              if (event.currentTarget.name=="bg_load8") {
                       var powerlines_mc:powerlines_png=new powerlines_png();
                       addChild(powerlines_mc);
                       powerlines_mc.x=powerlines_mc.mouseX;
                       powerlines_mc.y=powerlines_mc.mouseY;
                       powerlines_mc.name="powerlines_duplicate"+powerlines_inc;
                       powerlines_inc++;
                       powerlines_mc.startDrag(false);
                      powerlines_mc.addEventListener(MouseEvent.MOUSE_UP, stdrag);
              if (event.currentTarget.name=="bg_load9") {
                       var tropical_mc:tropical_png=new tropical_png();
                       addChild(tropical_mc);
                       tropical_mc.x=tropical_mc.mouseX;
                       tropical_mc.y=tropical_mc.mouseY;
                       tropical_mc.name="tropical_duplicate"+tropical_inc;
                       tropical_inc++;
                       tropical_mc.startDrag(false);
                      tropical_mc.addEventListener(MouseEvent.MOUSE_UP, stdrag);
              if (event.currentTarget.name=="bg_load10") {
                       var waters_mc:waters_png=new waters_png();
                       addChild(waters_mc);
                       waters_mc.x=waters_mc.mouseX;
                       waters_mc.y=waters_mc.mouseY;
                       waters_mc.name="waters_duplicate"+waterthumb_inc;
                       waterthumb_inc++;
                       waters_mc.startDrag(false);
                      waters_mc.addEventListener(MouseEvent.MOUSE_UP, stdrag);
    Please suggest me if any  one.
    Regards,
    Viji. S

    Post AS3 questions in the AS3 forum, not the AS1/2 forum.

  • What's the role of 'throws' clause in method overriding

    I'm getting error when subclass "Parser" overrides method 'getInt()' which throws Exception but super class version don't. It is compiling without error when vice versa is true i.e., super class version throws exception but sub class version don't throw exception.
    What's the role of 'Throws' clause in method overriding?
    What's the rationale with the output of following program?
    class Parser extends Utils {
       public static void main(String [] args) {
         System.out.print(new Parser().getInt("45"));
      int getInt(String arg) throws Exception{
         return Integer.parseInt(arg);
    class Utils {
       int getInt(String arg)  { return 42; }
    }

    karthikbhuvana wrote:
    I'm getting error when subclass "Parser" overrides method 'getInt()' which throws Exception but super class version don't. It is compiling without error when vice versa is true i.e., super class version throws exception but sub class version don't throw exception.
    What's the role of 'Throws' clause in method overriding?
    What's the rationale with the output of following program?
    class Parser extends Utils {
    public static void main(String [] args) {
    System.out.print(new Parser().getInt("45"));
    int getInt(String arg) throws Exception{
    return Integer.parseInt(arg);
    class Utils {
    int getInt(String arg)  { return 42; }
    Supose you do:
    Utils u = new Parser();
    int i = u.getInt("XX");This would throw a NumberFormatException, which is a checked exception, yet the compiler doesn't know this because Util.getInt() has no throws clause. Such a loophole would defeat the whole point of having throws clauses.
    So a method can only implement or override another if the throws clause on the interface or superclass admits the possibility of throwing every exception that the implementing method can throw, thus code which calls the method from a superclass or interface reference doesn't get any unexpected exceptions.

  • Doubt about generic method

    i have a generic method has shown below
    public static <E extends Number> <E>process(E list){
    List<Interger> output = new ArrayList<Interger>(); or List<Number> output = new ArrayList<Number>();
    return output ;
    if delcare the output variable using Interger or Number . when i am returning the output . it is showing me compiler error and it suggests me to add cast List<E>. Why i not able understand. please clarify my doubt.
    Thanks
    Sura.Maruthi
    Edited by: sura.maruthi on Sep 21, 2008 9:48 PM

    Your method declaration is garbled; there can be only one <...> clause, eg
    public static <E extends Number> E process(E list);This declaration says that for any subclass E of Number, the method process takes a single E instance (called list!?) and returns a single E instance. A valid implementation would be
    return list;I'm guessing you want the parameter to have type List<E>?. Like this:
    public static <E extends Number> E process(List<E> list);This declaration says that for any subclass E of Number, the method process takes a list of E's and returns a single E instance. A valid implementation would be
    return list.get(0);Or perhaps you also want to return a list of numbers?
    public static <E extends Number> List<E> process(List<E> list);This declaration says that for any subclass E of Number, the method process takes a list of E's and returns another list of E's. A valid implementation would be
    return list;Note that you cannot just return a list of Integers or Floats, because your generic method must work for any subclass of Number, and you're promising to return back a list of the same type as the argument passed in.
    Edited by: nygaard on Sep 22, 2008 10:05 AM

  • Doubt regarding Generic methods

    I have 4 generics Methods getEJBHome,getEJBLocalHome ,findEJBLocalHomeAndPopulateCache,findEJBHomeAndPopulateCache
         public <T extends EJBHome> T getEJBHome(final String jndiName,final Class<T> ejbHomeClass) throws NamingException,ClassCastException{
              T ejbHome=null;
              try{
                   if(serviceLocatorCache.containsKey(jndiName)){
                        ejbHome=(T)serviceLocatorCache.get(jndiName);     
                   else{
                        ejbHome=findEJBHomeAndPopulateCache(jndiName,ejbHomeClass);
              catch(NamingException namingException ){
                   System.err.println("Exception in getEJBHome ["+namingException.getMessage()+"]");
                   throw namingException;
              catch(ClassCastException classCastException ){
                   System.err.println("Exception in getEJBHome ["+classCastException.getMessage()+"]");
                   throw classCastException;
              return ejbHome;
         private <T extends EJBHome> T findEJBHomeAndPopulateCache(final String jndiName,final Class<T> ejbHomeClass) throws NamingException{
              T ejbHome=null;
              try{
                   ejbHome=(T)javax.rmi.PortableRemoteObject.narrow(context.lookup(jndiName),ejbHomeClass);
                   serviceLocatorCache.put(jndiName,ejbHome);
              catch(NamingException namingException){
                   System.err.println("Exception in findEJBHomeAndPopulateCache ["+namingException.toString()+"]");
                   throw namingException;
              return ejbHome;
         }i am calling findEJBHomeAndPopulateCache like normal method call,When i try to call findEJBLocalHomeAndPopulateCache from getEJBLocalHome it shows compile time error .
         public <T extends EJBLocalHome> T getEJBLocalHome(final String jndiName) throws NamingException{
              T ejbLocalHome=null;
              try{
                   if(serviceLocatorCache.containsKey(jndiName)){
                        ejbLocalHome=(T)serviceLocatorCache.get(jndiName);     
                   else{
                        ejbLocalHome=this.<T>findEJBLocalHomeAndPopulateCache(jndiName);
                        //ejbLocalHome=findEJBLocalHomeAndPopulateCache(jndiName); ERROR
              catch(NamingException namingException ){
                   System.err.println("Exception in getEJBLocalHome ["+namingException.getMessage()+"]");
                   throw namingException;
              catch(Exception exception ){
                   System.err.println("Exception in getEJBLoacalHome ["+exception.getMessage()+"]");
                   throw new NamingException("Exception in getEJBLoacalHome ["+exception.getMessage()+"]");
              return ejbLocalHome;
         }when i try to call method findEJBLocalHomeAndPopulateCache like ejbLocalHome=findEJBLocalHomeAndPopulateCache(jndiName);
    i am getting compile time error
    ServiceLocator.java:133: type parameters of <T>T cannot be determined; no unique maximal instance ex
    ists for type variable T with upper bounds T,javax.ejb.EJBLocalHome
        [javac]                             ejbLocalHome=findEJBLocalHomeAndPopulateCache(jndiName);
        [javac]     ^
    when i am calling that method like
    this.<T>findEJBLocalHomeAndPopulateCache(jndiName); it is not showing any error.normally we are invoking generic methods like normal methods ?
    Why i am getting a compile time error for findEJBLocalHomeAndPopulateCache method?
    method findEJBLocalHomeAndPopulateCache is as shown
         private <T extends EJBLocalHome> T findEJBLocalHomeAndPopulateCache(final String jndiName) throws NamingException{
              T ejbLocalHome=null;
              try{
                   ejbLocalHome=(T)context.lookup(jndiName);
                   serviceLocatorCache.put(jndiName,ejbLocalHome);
              catch(NamingException namingException){
                   System.err.println("Exception in findEJBLocalHomeAndPopulateCache ["+namingException.toString()+"]");
                   throw namingException;
              return ejbLocalHome;
         }Plz help

    Hi Ben,
    Thanks for your replay, Can you please tell me why in first case ie getEJBHome method call findEJBHomeAndPopulateCache(jndiName,ejbHomeClass) not causing any error.In both case upper bound of ‘T’ is EJBLocalHome .Kindly give me a clear idea.
    Plz help

  • Generic method signatures

    I've searched but can't find that a question I have has been asked (or answered). I apologize in advance if it has. Here is my question.
    In Java Generics FAQ by Angelika Langer states in FAQ 802 ( [http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#FAQ802] ) "the type parameters of a generic method including the type parameter bounds are part of the method signature."
    In FAQ 810, many examples are presented of method declarations, including generic ones, and their corresponding method signatures. For example,
    <T> T method(T arg) has the following signature in the example:
    <$T1_extends_Object>method($T1_extends_Object>)
    It would seem to be intuitively clear that the type parameter and bounds would be part of the method signature but I can't seem to find such a stipulation/requirement of such in the Java Language Specification. Anybody know where it's stipulated in the JLS?
    Best Regards

    user13143654 wrote:
    Yeah, I know. The title of the subsection is "Determining Method Signature," but then it never seems to expressly do that other than in some ephemeral wafting byproduct of overload resolution.I wouldn't call it "ephemeral" and "wafting." It's pretty specific. If you're looking for the $T1_extends_Object notation, you won't find it. That's not part of the spec.
    I can't seem to find a specific spot in the subsection where I can say "OK, now I've got the method signature and now can proceed to ..." Well, it goes on to Phase 3, and then on to 15.12.2.5 Choosing the Most Specific Method. I'm not sure what you're looking for. It does describe in detail how we get from all the methods in the universe, to which type's methods we'll be considering to which signatures could match to which one is the best match. I don't know what else you're looking for.
    If you're looking for somebody to digest, translate, and simplify all that for you, good luck, but it ain't gonna be me. :-)
    If you have specific questions about smaller pieces of it I (or somebody else) might be able to help out. At the moment though, your question is rather vague.
    Edited by: jverd on May 3, 2011 1:48 PM

  • Generic  method to execue procedure

    Hi I was wondering if there was a way to write a generic method to execute a stored procedure in my EJB. I was thinking of the input parameters as being the data source, procedure name, and an array of parameters. I'm new to java and therefore I didn't know if I should be using a callable statement for prepared statement for this. Also how to get around the problen of knowing my datatype when trying to set parameters for a statement since each parameters expects you to provide a specific set method for data type.
    V

    Whoops sorry about the half broken code.
    javax.naming.InitialContext ctx = new javax.naming.InitialContext();
    javax.sql.DataSource ds =                    (javax.sql.DataSource) ctx.lookup("jdbc/sybase");
    conn = ds.getConnection();
    cstmt =     conn.prepareCall(
              "{call dbo.ModifyExchange (?,?,?,?,?,?,?,?,?,?,?,?)}");
    cstmt.setObject(1, (Object) inputs[0]);
    cstmt.setObject(2, (Object) inputs[1]);               
    cstmt.setObject(3, (Object) inputs[2]);
    cstmt.setObject(4, (Object) inputs[3]);
    cstmt.setObject(5, (Object) inputs[4]);
    cstmt.setObject(6, (Object) inputs[5]);
    cstmt.setObject(7, (Object) inputs[6]);
    cstmt.setObject(8, (Object) inputs[7]);
    cstmt.setObject(9, (Object) inputs[8]);
    cstmt.setObject(10,(Object) inputs[9]);
    cstmt.setObject(11,(Object) inputs[10]);
    cstmt.setObject(12,(Object) inputs[11]);
    System.out.println("ExecuteUpdate Beginning");
    result = cstmt.executeUpdate();
    When I execute it I get "com.sybase.jdbc2.jdbc.SybSQLException: Implicit conversion from datatype 'VARCHAR' to 'TINYINT' is not allowed. Use the CONVERT function to run this query."
    Any ideas?

  • Generic method specialization

    I discovered today that it is possible overload a generic method with a non-generic one. Sounds reasonable, but I hadn't thought about it:
    class Util {
      public static <T> boolean isEmpty(T t) {
        return t == null;
      public static boolean isEmpty(String s) {
        return s == null || s.trim().equals(""");
      public static <A extends HasEmptyTest> boolean isEmpty(A a) {
        //class HasEmptyTest declares method isEmpty
        return a == null || a.isEmpty();
    }My question: Do you consider this in good style or feature abuse?
    Thanks for your response,

    Since generic methods may be substituted with their "erased" variants, your question boils down to this, totally non-generic, question:
    Is it advisable to overload a method with an argument of type A with a version that has an argument of type B when a widening conversion exists from A to B or vice versa?
    I'd answer: No, it's not advisable. It may lead to surprising behaviour.

  • Generic method - UnmarshalException (ClassNotFoundException)

    The mechanism was working fine until I added a generic method to the interface. Now it fails on a call to the new method.
    Here's the relevant code: public interface MyServer extends Remote {
        <T extends pub.beans.Bean> T getBeanAs ( Class<T> clazz, int key )
        throws RemoteException;
    public final class MyServerImpl implements MyServer {
        public synchronized <T extends pub.beans.Bean> T
                     getBeanAs ( final Class<T> clazz, final int key )
        throws RemoteException {
            Object bean = null;
            if( clazz == AbcBean.class )  {
                Abc obj = getObj( key );
                if( obj != null )  {
                    AllBeanTranslator x = new AllBeanTranslator();
                        * Translates an entity bean at the core of obj to external form.
                        * Core Data Object is class AbcDO.
                        * Returned object is class AbcBean.
                    bean = x.translateDO( obj.getData() );
            }  else  {  // ...
            return clazz.cast( bean );
    class Client  {
       public static void main ( final String[] args )
        throws Exception {
            System.setProperty("java.security.policy", "./security.policy" );
            if( System.getSecurityManager() == null ) {
                System.setSecurityManager(new RMISecurityManager());
            MyServer server = (BseServer)Naming.lookup( "MyServer" );
            AbcBean aBean = server.getBeanAs( AbcBean.class, 48 );
    // exception ^^^
    }This throws an exception on a class that the Client should know nothing about: AbcDO. The AbcBean hierarchy never references it. Here's the exception stack: Exception in thread "main" java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
         java.lang.ClassNotFoundException: beans.AbcDO
         at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:178)
         at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:178)
         at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:132)
         at $Proxy0.getBeanAs(Unknown Source)
         at Client.main(Client.java:61)
    Caused by: java.lang.ClassNotFoundException: beans.AbcDO
         at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
         at java.security.AccessController.doPrivileged(Native Method)
         at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
         at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
         at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
         at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
         at java.lang.Class.forName0(Native Method)
         at java.lang.Class.forName(Class.java:247)
         at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:434)
         at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:165)
         at java.rmi.server.RMIClassLoader$2.loadClass(RMIClassLoader.java:620)
         at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:247)
         at sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:197)
         at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1575)
         at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1496)
         at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1732)
         at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
         at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
         at java.beans.PropertyChangeSupport.readObject(PropertyChangeSupport.java:478)
         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
         at java.lang.reflect.Method.invoke(Method.java:597)
         at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974)
         at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1849)
         at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
         at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
         at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1947)
         at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1871)
         at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
         at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
         at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1947)
         at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1871)
         at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
         at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
         at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
         at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:306)
         at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:155)
         ... 4 moreAnother thing that puzzles me: Why no stub? When I saw that I turned on Stub Generation (I'm using Genady's RMI Eclipse Plug-in) but that caused a world of problems so I turned it back off.

    Just making them transient isn't the end of the solution, btw,
         * ChangeSupport serializes any serializable listeners.
         * If the listener is serializable but unknown to the codebase
         * causes UnmarshalException so best make these transient.
        protected transient PropertyChangeSupport pcs;
        protected transient VetoableChangeSupport vcs;After de-serialization pcs and vcs are null and of course the listeners are gone. AbcDO class uses events internally so they need to be re-established. Here's what I did, though I can think of at least two other solutions.
      // Normal constructor - not run during de-serialization
      protected AbcDO ( )  { 
          this.pcs = new PropertyChangeSupport( this );
          addPropertyChangeListener( this );
          this.vcs = new VetoableChangeSupport( this );
          addVetoableChangeListener( new AbcValidator() );
          this.SubObj = new SubObj ();
          this.SubObj .addPropertyChangeListener( this );
       * Re-establish transients after de-serialization.
       * Note how much this looks like the ctor.
       * @return this ready to rock again
       * @throws ObjectStreamException
      private Object readResolve ( )  throws ObjectStreamException  {
          this.pcs = new PropertyChangeSupport( this );
          addPropertyChangeListener( this );
          this.vcs = new VetoableChangeSupport( this );
          addVetoableChangeListener( new AbcValidator() );
          if( this.SubObj != null ) // should be impossible - subObj is final
              this.SubObj .addPropertyChangeListener( this );
          return this;
      }     Note that readResolve() may not be appropriate for a non-final class (see Effective Java). Note also that subObj needs its PropertyChangeSupport re-established.

  • Generic method

    Hi all,
    i have a question related to generic method in a non-generic class.
    the following code cannot be compiled. but I don't know why.
    public class G
           void print(Integer i)
              System.out.println("Inte");
         void print(String s)
              System.out.println("String");     
            <T> void callprint(T t)
              print(t);
            public static void main(String args[])
                    G g = new G();
                    g.callprint(new Integer(5));
    }Edited by: 812302 on Nov 16, 2010 6:58 PM
    Edited by: 812302 on Nov 16, 2010 6:59 PM

    Did you bother to read the error message. I'm sure it says something about not finding the print method and nothing to do with Generics. BTW you use square brackets for code tags or before and after your code.                                                                                                                                                                                                                                                                                                                                                                                                                                               

  • Generic method signature help

    Hello All,
    I'm confused about the following generic method signature . Compilation fails
    public class Animal{}
    public class Dog extends Animal{}
    public <E super Dog> List<E> methodABC(List<E> list){
    The compiler gives the following error
    E cannot be resolved to a type
    E cannot be resolved to a type
    Syntax error on token "super", , expected
    if i change the declaration of E to <E extends Dog>, no compiler error.
    An early response will be highly appreciated. Thanks in advance.
    Kind Regards.
    Hasnain Javed Khan.

    you cannot use "super" on a type variable, only on wildcards

  • How do I gain type safety with a generic method taking a class object?

    How do I achieve type safety with the following code without getting a compile error?
    import java.util.ArrayList;
    import java.util.List;
    public class Main {
        public static void main(String[] args) throws Exception {
            ListenerHolder th = new ListenerHolder();
            List<TestObject<String>> list = createTestObjectList();
            /* *** compiler error here *** */
            th.addListener(TestObject.class, list);
        private final static List<TestObject<String>> createTestObjectList() {
            List<TestObject<String>> list = new ArrayList<TestObject<String>>();
            return list;
        private final static class ListenerHolder {
                /* *** my generic method *** */
                public <T> void addListener(Class<T> listenerType, List<T> listener) { }
        private final static class TestObject<T> { }
    }The compiler error is:
    C:\java\Main.java:11: <T>addListener(java.lang.Class<T>,java.util.List<T>) in Main.ListenerHolder cannot be applied to (java.lang.Class<Main.TestObject>,java.util.List<Main.TestObject<java.lang.String>>)
    Thanks in advance,
    Dan

    dandubois wrote:
    Thanks for the help, that is exactly what I wanted to know.
    It didn't occur to me that TestObject<T> would in some respects be considered as an 'extends' of TestObject as I know the compiler converts them all back to plain TestObjects.Maybe I should have written TestObject<?>, to make it more obvious. There's some supertype/subtype relation diagram in the Generics FAQ somewhere, if you need more detailed information.
    In the end, I think jtahlborn's solution might be more appropriate in the described scenario, so you should go for it.

Maybe you are looking for

  • Free goods determination in the delivery document ??????????

    Hello All I am working on SD module I have a problem that I created a sales order that for every 100 pc 2 free pc will be given then I created the delivery order for 50 pc only but the system puts 2 free pc I tried again to change the delivery quanti

  • How to get info about available Toshiba updates?

    I have noticed that this has taken over from the online product information button. I was wondering how do I know now when there is an update availabe for Toshiba specific software and hardware?

  • I can't import P2 footage

    I have an old project that needs some changes. The footage I need to add was never imported the first time around. When I go to the log and transfer window, I can't add the P2 folder for this project, or any project for that matter. I'm using FCP 6.0

  • Warning: SUID file....will not be repaired

    I'm getting this error whenever I try to repair permissions. This is a brand new, clean install or 10.5. I've never seen this before. I know there have been some issues with repairing permissions in 10.5 but I've not see this particular error. Any on

  • Oracle 8i and COM + (MTS) on the same computer

    I don't have additional server to follow Microsoft recomendation to have Oracle and COM + on separate computers. What type of problems I may face if I put Oracle and COM + (MTS) on same server computer?