Use generic Wildcard in interface level java - java

This is related to java generic wild card. I need to understand how this happens and need solution.
Ex : I have a interface names Processer.
public interface Processer<X> {
<P> void process(P parent, X result);
}
I want to make P as wildcard. but it is not allowed to use wildcard ( ? ) when defining.
When I implement this interface and let IDE to generate implemented methods it generate as follow.
public class FirstProcesser implements Processer<String> {
#Override
public <P> void process(P parent, String result) {
}
}
I want to modify this implementation as this.
public class FirstProcesser implements Processer<String> {
#Override
public void process(User parent, String result) {
}
}
But it gives compile errors that FirstProcesser should be abstract or implement all the abstract methods.
I need to know why this is happening and a solution.

Overriding
You can't override a method
(generic or not)
with one that takes a narrower parameter type.
If you could, it would be impossible for the compiler to tell whether any given method call would be
(future tense)
legal.
An example without any generics at all, which will fail with exactly the same error:
public class X {
public void f(Object o) {
}
}
class Y extends X {
#Override
public void f(String s) {
}
}
Compiling this fails with:
X.java:8: error: method does not override or implement a method from a supertype
#Override
^
1 error
If it were legal, then it would be impossible to reliably compile even very simple methods like:
public static void f(X x) {
x.f(5);
}
If x were an actual X object, that code would work fine, but if x were a Y subtype, it would fail, because 5 is not a String.
This is why the above definition of Y.f is not allowed to override X.f.
By changing FirstProcesser to accept only User objects, you are causing the same problem.
Chain of Responsibility
The
chain of responsibility pattern on Wikipedia
doesn't look much like what you're trying to build.
I can think of two things you might be trying to do...
1.
If the parent parameter is supposed to be the previous handler in the chain, then it should be of type Processer<X>:
public interface Processer<X> {
void process(Processer<X> parent, X result);
}
class StringProcesser implements Processer<String> {
#Override
public void process(Processer<String> parent, String result) {
}
}
2.
If the type of parent is part of the decision-making process, each handler should store a collection of the Class objects it can handle.
The process method should then see if parent.getClass() is in that collection.
A partial definition might look something like:
public interface Processer<X> {
void process(Class<?> parent, X result);
}
class StringProcesser implements Processer<String> {
private Set<Class<?>> classes = new HashSet<Class<?>>();
public StringProcesser(final Iterable<Class<?>> classes) {
for (final Class<?> c : classes) {
this.classes.add(c);
}
}
#Override
public void process(Class<?> parent, String result) {
if (this.classes.contains(parent)) {
System.err.println("Handling...");
System.out.println(result);
return;
}
System.err.println(
"Can't handle. Try next Processer."
);
// ...
}
}
Note that where the generic type parameter <X> and where the wildcard <?> show up depends on what you're trying to do.
PS: "Processer" should be spelled "Processor".

Related

Combining different types of command interfaces using generics/inheritance

I'm using the command pattern to encapsulate logic in "command" objects. I currently have two types of command interfaces:
public interface ObjectCommand
{
public void execute(Object object);
}
And one that makes the execute method return something:
public interface ObjectToArrayCommand
{
public Object[] execute(Object object);
}
I was wondering if I could combine these two different interfaces into one interface, or have both share the same superclass interface using generics and/or inheritance, for example something like:
public interface Command<T,U>
{
public U execute(T t);
}
The problem I have with this scheme is that I cannot make parameter "U" be "void/no object". Is there another way?
I know I can use subclasses to give parameters that are MORE specific, like "Object" can become "String" in a subclass and it would still compile. But again, "Object" cannot become "void".
The reason I want to combine these two into one interface is because it is easier (conceptually speaking) if EVERY command implements the same interface instead of having two (or more) types of commands that are being used together.
What you are looking is java.lang.Void , a placeholder for void keyword
public interface ObjectCommand
{
public void execute(Object object);
}
public interface ObjectToArrayCommand
{
public Object[] execute(Object object);
}
can be combined as
public interface Command<T, U> {
public U execute(T t);
}
class CheckGenerics {
public static void main(String[] args) {
Command<Object, Class<Void>> command1 = new Command<Object, Class<Void>>() {
#Override
public Class<Void> execute(Object t) {
return Void.TYPE;
}
};
Command<Object, Object[]> command2 = new Command<Object, Object[]>() {
#Override
public Object[] execute(Object t) {
return new Object[] { t };
}
};
Class<Void> a = command1.execute(new Object());
System.out.println(void.class == a); // prints true
Object[] b = command2.execute(new Object());
System.out.println(b);
}
Check the documentation of Void Class here ,the javadoc states that
The Void class is an uninstantiable placeholder class to hold a reference to the Class object representing the Java keyword void..Note that Void class cannot be instantiated,which is precisely what we want

Overloading / generics in Java

I want to run certain tests in Lists. The Lists can contain entirely different classes.
I have one method to check the consistency of the list - not null, not empty, no more than x elements. This is common to all the lists. Then I want to test each of the objects, using overloading.
The idea would be something like:
public static <T> void check(List<T> list) {
//do general checks
for (T element : list) {
check(element);
}
}
and then
public static void check(SomeType element) {...}
public static void check(SomeOtherType element) {...}
But I also had to add a method like this:
public static void check(T element) {...}
And this was called at runtime - not my other methods with the specific classes. Although the class was exactly the same. I'm evidently missing some generics understanding.
Now if I don't use the general method at all and try to solve it this way:
public static void check(List<SomeType> list) {...}
public static void check(List<SomeOtherType> list) {...}
Compiler error - "Method check(List) has the same erasure check(List) as another method..."
So is there any elegant solution for this? I could just use different method names but would like to know how it's possible without that.
Thanks!
This isn't something about generics that you're missing. Java does not have double dispatch. The call to check must be resolved at compile-time, and check(T) is the only match since the compiler can't tell if T is SomeType or SomeOtherType in a given scenario. It needs to choose one method to call that will work for all possible Ts.
This is sometimes solved using the visitor pattern.
The problem should be solved by the caller. When it instanciate your class with a concrete type for T, it should also pass an instance of Checker<T> with the same concrete type:
public class SomeClass<T> {
private List<T> list;
private Checker<T> checker;
public SomeClass(Checker<T> checker) {
this.checker = checker;
}
public void check() {
checker.check(list);
}
}
public interface Checker<T> {
public void check(List<T> list);
}
...
SomeClass<Foo> someClass = new SomeClass<Foo>(new Checker<Foo>() {
#Override
public void check(List<Foo> list) {
// do whatever you want here
}
});
You can use instanceof to dispatch:
public static <T> void check(List<T> list) {
for (T element : list) {
check(element);
}
}
public static void check(T t) {
if (t instanceof SomeType) {
SomeType someType = (SomeType) t;
// code for SomeType ...
} else if (t instanceof OtherType) {
OtherType otherType = (OtherType) t;
// code for OtherType ...
} else {
// we got a type that we don't have a method for
}
}
With generics, the type parameter is actually erased during compilation, and the list object don't know anything about the static type of the object it contains. Since it doesn't know it, it can not use overloading to call methods with different parameters, because Java doesn't support multiple dispatch.
You have then three choices:
Make your objects implement a Checked interface with a check method that does the check logic. Downside is that the check logic is now dispersed in several places and it is not practical if you have objects of classes you don't have control of.
Use instanceof to call explicitly the check methods according to the dynamic type of the object. Downside is you potentially end up with a big if/else block a bit harder to maintain.
Implement the visitor pattern. Downside is that you have to change the object classes too, but the check logic stay in a single place.
Since the type of the variable is lost in check(List<T> list) you have two options:
1. Do different things by checking runtime type
check(T element) {
if (element.getClass().equals(SomeType.class)) {
check((SomeType) element);
} elseif (element.getClass().equals(SomeOtherType.class)) {
check((SomeOtherType) element);
}
This can be made a little more sophisticated, for example by wrapping each check in a Callable and using a Map<Class, Callable>
This is similar to visitor pattern.
2. Calling a virtual method on the element to be checked itself
If the checking logic can be pushed to the object to be checked itself (this is not necessarily a bad thing) then you don't need to check types:
interface Checkable { void check(); }
class SomeType implements Checkable { .... }
class SomeOtherType implements Checkable { .... }
Then:
public static <T extends Checkable> void check(List<T> list) {
for (T element : list) {
element.check();
}
}
These are the only two options, any implementation has to be a variation on one of these

java generics in Android

I don't understand the following code:
public class EventAdapter extends ArrayAdapter<Event>
{
public EventAdapter(Context context, int textViewResourceId,
List<Event> objects)
{
super(context, textViewResourceId, objects);
this.resource = textViewResourceId;
}
}
I am confused about the <Event> part in both cases. I understand it has something to do with Generics, but I don't understand it. I read http://docs.oracle.com/javase/tutorial/java/generics/, but still don't understand.
I do understand that objects is an ArrayList of objects of the type Event.
The part I don't understand is extending an ArrayAdapter with the Type <Event>. What does this signify?
extends ArrayAdapter<Event>
The type restriction here will influence on the return types of methods in the class, and the argument types of methods.
Here is an example, if you have a class:
class SomeClass<T> {
protected T value;
public void setValue (T value) {
this.value = value;
}
public T getValue () {
return value;
}
}
And if you have another class:
class SubClass extends SomeClass {
#Override
public void setValue (Event value) { // Fail! It is not overriding the super class' method.
this.value = value; // Warning! Unchecked types (maybe inconsistent).
}
}
If you remove the #Override annotation, it will run. But the extends SomeClass is useless and might cause problem if you keep it there -- there will be two very similar methods: setValue(Event) and super.setValue(T). Now the question is will the subclass have access to the super.setValue(T) method? I will explain it in the end, see "A missing type parameter bounding example".
So, you need to specify the type in declaration:
class SubClass extends SomeClass<Event> {
#Override
public void setValue (Event value) { // Correct now!
this.value = value;
}
}
Also, if you declare an inconsistent type:
class SubClass extends SomeClass<String> {
#Override
public void setValue (Event value) { // Fail! Not overriding.
this.value = value; // Fail! Inconsistent types.
}
}
So the type restricts the behavior of class body.
A missing type parameter bounding example:
import java.lang.reflect.*;
class Super<T> {
public void method (T t) {
System.out.println("Hello");
}
public void method2 () {
}
}
public class Test extends Super {
/*public void method (Object t) {
System.out.println("world");
}*/
/*public <T> void method (T t) {
}*/
public static void main (String args[]) {
new Test().method("");
for (Method m : Test.class.getMethods()) {
System.out.println(m.toGenericString());
}
}
}
If I comment method() in the subclass, it is compiled with a warning: Test.java uses unchecked or unsafe opertations. In the running result, it turned the generic type T into Object: public void Test.method(java.lang.Object).
If I only uncomment the first method() in the subclass, it is compiled with no warnings. In the running result, the subclass owns one public void Test.method(java.lang.Object). But it doesn't allow #Override annotation.
If I only uncomment the second method() in the subclass (which also has a generic type bounding), the compile fails with an error: name clash. It also doesn't allow #Override annotation. If you do so, it throws a different error: method does not override.
method2() is inherited by the subclass unanimously. But you also can't write the following code:
in superclass: public void method2 (Object obj) and in subclass: public <T> void method2 (T obj). They are also ambiguous and is not allowed by the compiler.
Here's my simplistic way of looking at generics in this case. Given the definition:
public class EventAdapter extends ArrayAdapter<Event>
I read it as: "An EventAdapter IS-A ArrayAdapter OF Event objects."
And I take List<Event> objects to mean a List of Event objects.
Collections are containers for objects, while Generics define what they can contain.
This assigns a value for the generic parameter in ArrayAdapter in a way that takes away control from the user of the EventAdapter class.
Any method overriding here can then replace T with Event and Event can be used inplace of T without casts.
This is the general definition of generics.
That this is allowed in this case is defined in the spec. While the exact behaviour is not defined in that section I think it is in line with all other generic behaviour as far as I can see.
While I see the construct here the first time, after some thinking it really isn't anything unusual.

avoiding instanceof

I have a set of POJOs with a common superclass. Those are stored in a two-dimensional array of type superclass. Now, I want to obtain an object from the array and use methods of the subclass. This means I have to cast them to the subclass. Is there a way to do this without using instanceof?
Update: As a concrete example: http://obviam.net/index.php/the-mvc-pattern-tutorial-building-games/ See: "Add new actions (attack) when an enemy is clicked"
Yes - you can do it by inverting the flow: instead of your code doing something when the instance of the base class is of a specific type, pass an action item to the object, and let the object decide whether to perform it or not. This is the basic trick behind the Visitor Pattern.
interface DoSomething {
void act();
}
abstract class AbstractBaseClass {
abstract void performAction(DoSomething ds);
}
class FirstSubclass extends AbstractBaseClass {
public void performAction(DoSomething ds) {
ds.act();
}
}
class SecondSubclass extends AbstractBaseClass {
public void performAction(DoSomething ds) {
// Do nothing
}
}
AbstractBaseClass array[] = new AbstractBaseClass[] {
new FirstSubclass()
, new FirstSubclass()
, new SecondSubclass()
, new FirstSubclass()
, new SecondSubclass()
};
for (AbstractBaseClass b : array) {
b.performAction(new DoSomething() {
public void act() {
System.out.println("Hello, I'm here!");
}
});
}
If you know they're of the subclass type, then just cast them directly without an instanceof check.
But putting them in a superclass-typed array is telling the compiler to discard the information that they're actually of the subclass type. Either your superclass should expose those methods (perhaps as abstract), or your array should be of the subclass type (so you're not telling the compiler to forget the actual type of the objects), or you'll have to suck it up and do the cast (possibly with the instanceof test).
The only other notable alternative is that you might experiment with the visitor pattern, which passes an action to the object and lets the object decide what to do with it. That lets you override classes to ignore or perform the actions based on their runtime type.
You can try to use the Visitor design pattern.
http://en.wikipedia.org/wiki/Visitor_pattern
You have to ask yourself, why do you need to know their type, maybe this can be replaced with the use of an abstract method in the super class, that every one of them can implement according the desired result.
abstract class A{
abstract void visit();
}
class B extends A{
void visit() { print("B"); }
}
class C extends A {
void visit() { print("C"); }
}
I would avoid casting them in the first place.
Really think about what you're trying to do, and if they should be in the same collection like that.
If you have something like this
for(MyObj o : array) {
if(o instanceof A) {
((A)o).doA();
}
if(o instanceof B) {
((B)o).doB();
}
}
consider this instead
abstract class MyObj {
abstract void doIt();
}
class A {
void doIt() { doA(); }
}
class B {
void doIt() { doB(); }
}
Expose the method in the superclass, and then use overriding. Provide an empty implementation in the base class so that subclasses can ignore the action if needed.

Method with typed list and inheritance

I have some troubles with a method having a typed List parameter, inherited from another (typed) class.
Let's keep it simple :
public class B<T> {
public void test(List<Integer> i) {
}
}
The B class has a useless generic T, and test() want an Integer List.
Now if I do :
public class A extends B {
// don't compile
#Override
public void test(List<Integer> i) {
}
}
I get a "The method test(List) of type A must override or implement a supertype method" error, that should not happen.
But removing the type of the list works... although it doesn't depend on the class generic.
public class A extends B {
// compile
#Override
public void test(List i) {
And also defining the useless generic below to use the typed list
public class A extends B<String> {
// compile
#Override
public void test(List<Integer> i) {
So I'm clueless, the generic of B should have no influence on the type of the test() list. Does anyone have an idea of what's happening?
Thanks
You're extending the raw type of B, not the generic one. The raw one effectively does not have a test(List<Integer> i) method, but a test(List) method.
If you switch to raw types, all generics are replaced by raws, regardless of whether their type was filled in or not.
To do it properly, do
public class A<T> extends B<T>
This will use the generic type B<T>, which includes the method you want to override.
When you remove use a class without generics (and use it raw), all generics from class methods are forgotten.
Due this reason when you inform the generic type on the second case you get it working.
This:
class T<G> {
public void test(G g);
}
in this case:
class A extends T {
}
will look like this:
class T {
public void test(Object g);
}
This was a java puzzle presented on Google IO 2011 you can see video here

Categories