Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic method in Java without generic argument

Tags:

java

generics

In C# I can do actually this:

//This is C# static T SomeMethod<T>() where T:new() {   Console.WriteLine("Typeof T: "+typeof(T));   return new T(); }  //And call the method here SomeMethod<SomeClassName>(); 

But for some reason I can't get it to work in Java.

The thing I want to do is, to create a static method on a superclass, so the subclasses can be converted to XML.

//This is Java, but doesn't work public static T fromXml<T>(String xml) {   try {     JAXBContext context = JAXBContext.newInstance(T.class);     Unmarshaller um = context.createUnmarshaller();     return (T)um.unmarshal(new StringReader(xml));   } catch (JAXBException je) {     throw new RuntimeException("Error interpreting XML response", je);   } }  //Also the call doesn't work... fromXml<SomeSubObject>("<xml/>"); 
like image 705
doekman Avatar asked Feb 26 '09 12:02

doekman


People also ask

Can you have a generic method in a non-generic class?

Yes, you can define a generic method in a non-generic class in Java.

How do you call a generic method as a normal method?

Which of the following allows us to call generic methods as a normal method? Explanation: Type inference, allows you to invoke a generic method as an ordinary method, without specifying a type between angle brackets.

How do you declare a generic method in Java?

For static generic methods, the type parameter section must appear before the method's return type. The complete syntax for invoking this method would be: Pair<Integer, String> p1 = new Pair<>(1, "apple"); Pair<Integer, String> p2 = new Pair<>(2, "pear"); boolean same = Util. <Integer, String>compare(p1, p2);

How does a generic method differ from a generic type in Java?

Java Generic methods and generic classes enable programmers to specify, with a single method declaration, a set of related methods, or with a single class declaration, a set of related types, respectively. Generics also provide compile-time type safety that allows programmers to catch invalid types at compile time.


1 Answers

public static <T> T fromXml(Class<T> clazz, String xml) { 

Called as:

Thing thing = fromXml(Thing.class, xml); 

or more explicitly:

Thing thing = MyClass.<Thing>fromXml(Thing.class, xml); 

To be even more confusing you can have constructors that both construct a generic type and have a generic parameter themselves. Can't remember the syntax and have never seen it used in anger (you are probably better off with a static creation method anyway).

The cast (T) is unsafe, and you can't write T.class. So include the T.class as an argument (as JAXBContext.newInstance does) and throw a relevant exception if the type is wrong.

public static <T> T fromXml(Class<T> clazz, String xml) {     try {         JAXBContext context = JAXBContext.newInstance(clazz);         Unmarshaller um = context.createUnmarshaller();         Object obj = um.unmarshal(new StringReader(xml));         try {             return clazz.cast(obj);         } catch (ClassCastException exc) {              throw new RelevantException(                  "Expected class "+clazz+                   " but was "+obj.getClass()              );         }     } catch (JAXBException exc) {         throw new RelevantException(             "Error unmarshalling XML response",             exc          );     } } 

I believe the next version of JAXB (in 6u14?) has some convenience methods for this sort of thing in the JAXB class.

like image 194
Tom Hawtin - tackline Avatar answered Oct 03 '22 04:10

Tom Hawtin - tackline