Generic Method Pattern in Java

I am very new to Java generators and have spent an excessive amount of time looking for a suitable solution (if any).

I am trying to create adapters that handle objects of a particular type of class. As described below, the CAdapter class only handles CClass objects. I am trying to provide an abstract generic adapter that handles most of the work (like Java assemblies like LinkedList). Then I provide a specific adapter implementation for each type that should be supported.

// Classes public interface AInterface { public String toString(); } public class BClass extends AInterface { public String toString() { return "BClass "; } } public class CClass extends AInterface { public String toString() { return "CClass"; } } // Adapters public interface AdapterInterface<T extends AInterface> { public T getInterface(); } public class BAdapter implements AdapterInterface<BClass> { private BClass aInterface = null; public BClass getInterface() { return aInterface; } } public class CAdapter implements AdapterInterface<CClass> { private CClass aInterface = null; public CClass getInterface() { return aInterface; } } 

Firstly, I read that providing the CONCRETE implementation for such a universal adapter is disapproving (something about God killing a kitten)! Maybe someone can expand this?

Secondly, I had a problem with dynamically creating an adapter instance and the lack of a Java compiler. For example, I have a method:

 public <T extends AInterface> AdapterInterface<T> getAdapter(String type) { AdapterInterface<T> result = null; if (type.equals("C") { result = new CAdapter(); } return result; } 

Of course, the compiler will complain about the lack of CAdapter compliance. For any type of AInterface object, I would like to be able to load the correct adapter and process it accordingly. I do not understand the factory pattern to accomplish this.

Any thoughts would be greatly appreciated.

+4
source share
2 answers

My answer is a little redundant, but:

Everything that matters <T> means that "my caller knows what type this is, but I do not." So,

 AdapterInterface<T> result = null; 

Means: "I really do not know what type of result, regardless of what my interlocutor believes that is." The compiler complains about this:

 result = new CAdapter(); 

Since this code cannot assume that T is CClass.

In fact, there is no way to do this without casting (declaring a wild carded method means you need to pass the result when you name it). Throwing is your way of telling the compiler, “I know you have no way of knowing what it is, it's normal: I know. Believe me. Yes, you will get a warning. And that's fine.

Generics do not eliminate all castings, but allow you to do this only once . Instead of making throws everywhere, you need them only in one place, where you, the encoder, know for sure that you play games with types. The rest of the code, using only the adapter that you just created, can safely work with the generic type.

+3
source

Do not use generics here, covariant (or contravariant, never remembering which) return types seem to do what you want:

 interface AdapterInterface { public AInterface getInterface(); } class BAdapter implements AdapterInterface { private BClass aInterface = null; public BClass getInterface() { return aInterface; } } class CAdapter implements AdapterInterface { private CClass aInterface = null; public CClass getInterface() { return aInterface; } } public AdapterInterface getAdapter(String type) { AdapterInterface result = null; if (type.equals("C")) { result = new CAdapter(); } return result; } 

If you did not specify any other methods in the interfaces. The following also compiles with common classes:

 public AdapterInterface<? extends AInterface> getAdapter(String type) { if (type.equals("C")) { return new CAdapter(); } else { // … } } 

The reason your original method will not compile is because T is a certain unknown type that extends AInterface ; this does not mean "any type that extends from AInterface ". It is not possible to statically prove that the adapter you are returning is an adapter for the type that the caller needs.

+3
source

Source: https://habr.com/ru/post/1394310/


All Articles