Generic methods: how to express explicit type parameters?

Discussion in 'Java' started by z-man, Oct 1, 2006.

  1. z-man

    z-man Guest

    Hi all

    I'm struggling to solve this puzzle: I'm porting some C# code to Java
    regarding some invocations to a couple of generic methods.

    The problem is that the generic types of such generic methods cannot be
    inferred by the compiler as they only refer to the returning value
    (getter method: getEntry) and to some local variables inside the
    respective code bodies (both getter and setter methods: getEntry and
    setEntry).

    So, it seems that an explicit type parameter invocation is needed: C#
    supports it (see below), but I couldn't find an equivalent replacement
    in Java till now.

    Any idea?

    Many thanks.

    // C# version -------------------------------------
    public string Name
    {
    get{return GetEntry<string,MyStringType>("name");}
    set{SetEntry<string,MyStringType>("name",value);}
    }

    protected T GetEntry<T,TBase>(
    string key
    )
    where TBase : MyBaseType<T>
    {
    try{return (T)((TBase)entries[key]).Value;}
    catch{return default(T);}
    }

    protected void SetEntry<T,TBase>(
    string key,
    T value
    )
    where TBase : MyBaseType<T>, new()
    {
    if(!entries.ContainsKey(key))
    entries[key] = new TBase();

    ((TBase)entries[key]).Value = value;
    }

    // Java version -----------------------------------
    public String getName()
    {
    // Doesn't work! What's the equivalent syntax?
    return getEntry<String,MyStringType>("name");
    }

    public void setName(
    String value
    )
    {
    // Doesn't work! What's the equivalent syntax?
    setEntry<String,MyStringType>("name",value);
    }

    protected T <T,TBase extends MyBaseType<T>> getEntry(
    String key
    )
    {
    try{return (T)((TBase)entries.get(key))).getValue();}
    catch{return default(T);}
    }

    protected void <T,TBase extends MyBaseType<T>> setEntry(
    String key,
    T value
    )
    {
    if(!entries.containsKey(key))
    entries.set(key,new TBase());

    ((TBase)entries.get(key))).setValue(value);
    }
    z-man, Oct 1, 2006
    #1
    1. Advertising

  2. z-man

    Piotr Kobzda Guest

    z-man wrote:

    > // Java version -----------------------------------
    > public String getName()
    > {
    > // Doesn't work! What's the equivalent syntax?
    > return getEntry<String,MyStringType>("name");


    return this.<String,MyStringType>getEntry("name");

    > }
    >
    > public void setName(
    > String value
    > )
    > {
    > // Doesn't work! What's the equivalent syntax?
    > setEntry<String,MyStringType>("name",value);


    return this.<String,MyStringType>setEntry("name",value);

    > }
    >
    > protected T <T,TBase extends MyBaseType<T>> getEntry(
    > String key
    > )
    > {
    > try{return (T)((TBase)entries.get(key))).getValue();}
    > catch{return default(T);}
    > }
    >
    > protected void <T,TBase extends MyBaseType<T>> setEntry(
    > String key,
    > T value
    > )
    > {
    > if(!entries.containsKey(key))
    > entries.set(key,new TBase());
    >
    > ((TBase)entries.get(key))).setValue(value);
    > }


    But all this won't work together in Java, because of erasure...

    I think you need something like this:

    public class YourCSharpPort {

    public String getName() {
    return getEntry("name", MyStringType.class);
    }

    public void setName(String value) {
    setEntry("name", MyStringType.class, value);
    }


    Map<String, Object> entries;

    protected <T, TBase extends MyBaseType<T>>
    T getEntry(
    String key, Class<TBase> typeOfTBase) {
    TBase holder = typeOfTBase.cast(entries.get(key));
    return holder != null ? holder.getValue() : null;
    }

    protected <T, TBase extends MyBaseType<T>>
    void setEntry(
    String key, Class<TBase> typeOfTBase,
    T value) {
    TBase holder = typeOfTBase.cast(entries.get(key));
    if (holder == null && !entries.containsKey(key))
    entries.put(key, holder = newInstanceOf(typeOfTBase));
    holder.setValue(value);
    }


    protected <T> T newInstanceOf(Class<T> typeOfT) {
    try {
    return typeOfT.newInstance();
    } catch (InstantiationException e) {
    throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
    throw new RuntimeException(e);
    }
    }

    }


    HTH,
    piotr
    Piotr Kobzda, Oct 1, 2006
    #2
    1. Advertising

  3. z-man

    z-man Guest

    On 10/01/2006 10:31 PM, Piotr Kobzda wrote:
    > z-man wrote:
    >
    >> // Java version -----------------------------------
    >> public String getName()
    >> {
    >> // Doesn't work! What's the equivalent syntax?
    >> return getEntry<String,MyStringType>("name");

    >
    > return this.<String,MyStringType>getEntry("name");
    >
    >> }
    >>
    >> public void setName(
    >> String value
    >> )
    >> {
    >> // Doesn't work! What's the equivalent syntax?
    >> setEntry<String,MyStringType>("name",value);

    >
    > return this.<String,MyStringType>setEntry("name",value);
    >
    >> }
    >>
    >> protected T <T,TBase extends MyBaseType<T>> getEntry(
    >> String key
    >> )
    >> {
    >> try{return (T)((TBase)entries.get(key))).getValue();}
    >> catch{return default(T);}
    >> }
    >>
    >> protected void <T,TBase extends MyBaseType<T>> setEntry(
    >> String key,
    >> T value
    >> )
    >> {
    >> if(!entries.containsKey(key))
    >> entries.set(key,new TBase());
    >>
    >> ((TBase)entries.get(key))).setValue(value);
    >> }

    >
    > But all this won't work together in Java, because of erasure...
    >
    > I think you need something like this:
    >
    > public class YourCSharpPort {
    >
    > public String getName() {
    > return getEntry("name", MyStringType.class);
    > }
    >
    > public void setName(String value) {
    > setEntry("name", MyStringType.class, value);
    > }
    >
    >
    > Map<String, Object> entries;
    >
    > protected <T, TBase extends MyBaseType<T>>
    > T getEntry(
    > String key, Class<TBase> typeOfTBase) {
    > TBase holder = typeOfTBase.cast(entries.get(key));
    > return holder != null ? holder.getValue() : null;
    > }
    >
    > protected <T, TBase extends MyBaseType<T>>
    > void setEntry(
    > String key, Class<TBase> typeOfTBase,
    > T value) {
    > TBase holder = typeOfTBase.cast(entries.get(key));
    > if (holder == null && !entries.containsKey(key))
    > entries.put(key, holder = newInstanceOf(typeOfTBase));
    > holder.setValue(value);
    > }
    >
    >
    > protected <T> T newInstanceOf(Class<T> typeOfT) {
    > try {
    > return typeOfT.newInstance();
    > } catch (InstantiationException e) {
    > throw new RuntimeException(e);
    > } catch (IllegalAccessException e) {
    > throw new RuntimeException(e);
    > }
    > }
    >
    > }
    >
    >
    > HTH,
    > piotr



    Many thanks Piotr, I'll get a try of it!
    z-man, Oct 1, 2006
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Murat Tasan
    Replies:
    1
    Views:
    8,025
    Chaitanya
    Feb 3, 2009
  2. J.T. Conklin
    Replies:
    1
    Views:
    428
    David Hilsee
    Aug 11, 2004
  3. Andy
    Replies:
    5
    Views:
    494
    Shezan Baig
    Jan 30, 2005
  4. Replies:
    1
    Views:
    559
    Salt_Peter
    Dec 25, 2006
  5. minlearn
    Replies:
    2
    Views:
    445
    red floyd
    Mar 13, 2009
Loading...

Share This Page