开发者

Java generic parameter itself using generics?

开发者 https://www.devze.com 2022-12-13 05:45 出处:网络
I\'m trying to figure out how to structure a program using Java\'s generics, and wondering if I am doing something fundamentally wrong or just missing a simple bug in my code.

I'm trying to figure out how to structure a program using Java's generics, and wondering if I am doing something fundamentally wrong or just missing a simple bug in my code.

Say I have a generic class:

public interface Handler<T>{ 
 public void process(T t); 
}

Another generic class takes Handler as a generic parameter (pseudo code):

public int开发者_运维知识库erface Processor<S extends Handler<T>>{ //<== Error: cannot find symbol 'T'
 public void addHandler(S u); 
 public void process(T t);
}

Abstract implementation providing boiler-plate implementations

public abstract class ProcessorImpl<.....> implements Processor<.....>{
  ...
}

Think of a processor as an object that dispatches requests to process data to any number of handlers. Specific instances can be variations of process pipelines, intercepting filters, event systems, etc.

I'd like to be able to use it like the following:

Handler<String> myHandler1 = new HandlerImpl<String>();
Handler<String> myHandler2 = new HandlerImpl<String>();
Handler<Integer> myHandler3 = new HandlerImpl<Integer>();

Processor<Handler<String>> proc = ProcessorImpl<Handler<String>>();
proc.addHandler(myHandler1);
proc.addhandler(myHandler2);
proc.addhandler(myHandler3);//this should be an error!

I can't get it to work. On paper it looks like it should be trivial, any ideas?

Thanks


So each type parameter is only defined within the class, thus T isn't defined or available in Processor class.

You probably want to have Processor be:

public interface Processor<T>{
  public void addHandler(Handler<? super T> u); 
  public void process(T t);
}

Here you are declaring a Processor that can only handle events/input of a particular type, e.g. String, Integer, etc. So the following statement will be valid:

Processor<String> proc = ...
proc.addHandler(new Handler<String>());   // valid
proc.addHandler(new Handler<Object>());   // valid, as Strings are Objects too
proc.addHandler(new Handler<Integer>());  // invalid, not a String handler
proc.process("good");     // valid
proc.process(1);          // invalid, not a String

If Processor is intended to handle types at runtime and makes a dynamic dispatch based on the appropriate runtime type, then you can declare proc (in the last example) as Processor<?>. Then all the statements are valid.


These changes should work:

public interface Processor<T, S extends Handler<T>>

and

class ProcessorImpl<T, S extends Handler<T>>
    implements Processor<T, S>

and

Processor<String, Handler<String>> proc = new ProcessorImpl<String, Handler<String>>();


It shouldn't work, as your T=String and handlers of integers are not allowed. At compile time, your class will have method process(String t) and not process(Integer t).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号