Generic methods: how to express explicit type parameters?

Z

z-man

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);
}
 
P

Piotr Kobzda

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

return this. said:
}

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

return this. said:
}

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
 
Z

z-man

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!
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,740
Latest member
JudsonFrie

Latest Threads

Top