2

I'm new to generics, and am struggling with applying to my situation:

I currently have several SyncData Classes, one for each object type that I wish to sync. I'm looking at changing this to a single generic class SyncData. Within this class some parts of the code will use objects of type T, but I'd also like to reference static Methods of type T. This would enable me for example to specify a notification action (specific to the data type) to be called on completion of the sync.

I'm getting myself caught in a loop: to access the methods I need to define an interface that all the types will implement, in the generic T extends interface, and then I can reference the relevant methods of type T within my generic SyncData Class. However I can't specify a static method in an interface, and because I can't in the interface, I cant access it in my generic SyncData Class.

I've looked at various tutorials, questions here etc, maybe I'm missing the obvious, but I can't see the way forward - everything that comes up seams to refer to different issues with generics and static nethods. Any advice would be very much appreciated.

Edit:

As requested some sample code added to illustrate what I tried to do (I'm actually looking to use static methods at various other points within the code, but this illustrates the point).

Is it possible to access the static method of class T from within the SyncAction class (without making T extend DataType1 by which point there is no point using generics as T cannot be DataType2)?

public interface Syncable {
    //following needed or I can't access onSyncComplete in SyncAction
    public void onSyncComplete();
}

public class DataType1 implements Syncable {
    //constructor etc removed as irrelevant to question

    //Eclipse warns 'this static method cannot hide instance method from Syncable' 
    public static void onSyncComplete(){
        //do stiff here
    }
}

public class SyncAction<T extends Syncable>{
    //do all the syncing etc using multiple DataType1 objects

    T.onSyncComplete();
}
Nathan
  • 65
  • 10
  • What is the question? You should include a clear question, not a statement. That way it's lot easier to understand and clearer. – Anubian Noob May 17 '14 at 21:32
  • Please share a sample code to make it clear. – Braj May 17 '14 at 21:34
  • Sorry I'm looking for advice how to address the issue: is it possible to access static methdos in the way I want - I'll get some simplified code to add – Nathan May 17 '14 at 21:35
  • Why do they need to be static? – Evan Knowles May 17 '14 at 22:03
  • Two reasons- a) It allows me to access them without creating an instance b) As they do not interact with instance variables, they can be static. Other static methods I was hoping to create include a method to return an array of objects which are unsynced. – Nathan May 17 '14 at 22:11
  • the accepted answer is the same reason it won't work for what you are doing here –  May 17 '14 at 23:47

2 Answers2

1

Even though the onSyncComplete() method could be static, you must make them instance (ie non-static) methods for this to work.

The reason is that static methods (and fields) are not "inherited".

If you really want to have a static method, you could have your onSyncComplete() instance method call another (perhaps private) static method in its implementation.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
1

Few things:

Eclipse is correct in stating that your static version of onSyncComplete() is incorrect. From JLS seciton 8.4.8.2:

It is a compile-time error if a static method hides an instance method.

In this case, your static method is hiding the instance method defined in your interface, so you get an error.

This is because if such a thing were allowed there would be some ambiguity as to whether the static method or instance method were to be called, as you can invoke static methods on an instance (although that isn't really a good idea for readability, and is considered a mistake by some).


The reason you cannot call static methods on a generic type is that static methods are bound at compile time. Because generic types are erased during compilation to their bounding type (Syncable in your case), the compiler will not be able to figure out which static method to bind, and so emits an error.

awksp
  • 11,764
  • 4
  • 37
  • 44