Forum Stats

  • 3,855,574 Users
  • 2,264,523 Discussions
  • 7,906,071 Comments

Discussions

How do u define a class for supporting Generics?

843793
843793 Member Posts: 41,732 Green Ribbon
edited May 14, 2003 8:43AM in Generics
What I mean is, what all goes into defining a class[b] MyGenericClass which will support say <String> and <Integer> flavours ?

That is to say, to be able to support code like the following, what specific code do I need to write in MyGenericClass :
public void myMethod(MyGenericClass<String> myS)
{
    ...
}

public void myMethod(MyGenericClass<Integer> myI)
{
    ...
}
I haven't read up much of the documentation on the Generics feature though, so plz point me to some doc if it is a very "beginner" question !!!

Comments

  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    public class MyGenericClass<T> { }
    Then in MyGenericClass, use type T as you would use any other type.

    Pretty simple, huh? I don't see what others find so complicated about it.
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    public class MyGenericClass<T> { }
    Then in
    MyGenericClass, use type T as you would use any other
    type.
    Since I am not from a C/C++ background I will venture to ask another question here about using the definition above(just to clarify my doubts):

    How do I "use type T as you would use any other type."?

    If I want to support MyGenericClass<String> and MyGenericClass<Integer>, would I need to define two separate class files as:
    public class MyGenericClass<String>
    {
        public MyGenericClass<String>() // default Constructor
        {...}
            
        public void add(Object s)
        {
            if(!(s instanceof String)) 
                throw Exception(); // this is the String flavour
        }
    }
    and a similar class definition for Integer??? Seems stupid to me, I think I better do some reading up on this before asking questions...
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    If I want to support MyGenericClass<String> and MyGenericClass<Integer>, would I need to define two separate class files...

    Because Java Generics is fundamentally based on type erasure, a parameter to a generic class can't support types which aren't specified as part of its type hierarchy. This is why you must specify the interfaces a type parameter extends. In the case of an unadorned type parameter, the compiler assigns the type to be Object. Type erasure is the core reason why Java Generics is really nothing more than compiler-aided type-casting.

    If you want to write type-specific code, you have to do it the same way that you do it in any non-generic class or method - use reflection.

    God bless,
    -Toby Reyelts
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    I think viveksh just needs to know the following simple use.
    BTW I haven't used the Generics compiler myself, but this seems right from what I've seen 8^).

    You declare the class like this:

    public class MyGenericClass<T>{
    public void add(T s) {
    // within this function, s is treated as having type T
    }

    public T get() {
    // ...do something here...
    return T;
    }
    }


    You use the class like this:

    MyGenericClass<String> blah = new MyGenericClass<String>();
    blah.add("hello"); // this is OK
    blah.add(123); // the compiler will complain: wrong type
    String output = blah.get(); // this is OK
    Object obj = blah.get(); // this is OK too
    Integer bad = blah.get(); // this isn't
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    To clarify, you only declare the class once, but you can use it multiple times with different types, e.g.

    MyGenericClass<String> blah = new MyGenericClass<String>();
    blah.add("hello"); // this is OK

    MyGenericClass<Integer> blah2 = new MyGenericClass<Integer>();
    blah2.add(new Integer(123)); // this is OK
    blah2.add("the compiler will complain here");

    Unlike C++, no extra code is generated each time you use the class with a new type. (The class is actually compiled using Object instead of T; but the compiler still checks you're using the right types in every place you use it.)
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    Thanks for your inputs schapel, Toby and Jonathan. The only thing thats killing me now is that, is <T> a special keyword in the new Generics release, or you guys conincidentally chose <T> to represent a generic Type.... Looks like <T> is... just asking anyways...

    Thanks,
    Vivek.
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    AFAIK you can use any identifier between the < >'s (in your class definition). It's just like defining a local variable with an arbitrary name - this is a type variable, which when you later use the class will represent a specific type like String or Integer.

    You only see T a lot in examples because traditionally this capital letter represents an unknown type, just as x represents an unknown integer.
This discussion has been closed.