Nested Parameterized types in interface - java

I have following interfaces:
CacheKey interface:
public interface CacheKey<K extends Serializable> extends Serializable {
K get();
}
CacheValue interface:
public interface CacheValue<V extends Serializable> extends Serializable {
V get();
}
Cache interface:
public interface Cache<CacheKey<K extends Serializable>, CacheValue<V extends Serializable>> {
}
Cache interface doesn't compile. Error I get is:
[13,35] > expected
i.e. after CacheKey compiler doesn't like another opening angle bracket:
public interface Cache<CacheKey<
^
Is this not possible in Java?

You're missing a crucial step here : the implementation.
It's usually in the implementation that you want to define what the type of ? extends Serializable will be. You don't need to implement this in the Cache interface.
The interface only needs to know what its generics types will be, not the generics of their child : this is for the implementation.
Take a look at the example here below to understand what I exactly mean by that.
Addition : When your define something like Cache<CacheKey, CacheValue> you're not referring to the classes, but you're creation a generic alias. CacheKey could easily be replaced by Blabla and continue to have the same behaviour. The solution is to use extends to make sure we're talking about the type.
This was also the reason why Cache<CacheKey<...>> did not compile, because CacheKey is not referring to the class but is used as an alias
public interface CacheKey<K extends Serializable> extends Serializable {
K get();
}
public interface CacheValue<V extends Serializable> extends Serializable {
V get();
}
public interface Cache<K extends CacheKey<? extends Serializable>, V extends CacheValue<? extends Serializable>> {
void put(K key, V value);
}
public class CacheImpl implements Cache<CacheKey<String>, CacheValue<String>> {
#Override
public void put(CacheKey<String> key, CacheValue<String> value) {
// do whatever
}
}

Using a wildcard-bounded generic type, as suggested in other answers, isn't a great idea.
If you declare your class like this:
public interface Cache<K extends CacheKey<?>, V extends CacheValue<?>> {
}
then you would never be able to usefully invoke get() on the key or value, because they would only ever return Serializable. And Serializable is a useless class (it's barely different to Object actually inside your code).
Instead, I would simply declare the class like:
public interface Cache<K extends Serializable, V extends Serializable> {
and then declare that the put method takes a CacheKey<K> and a CacheValue<V>:
void put(CacheKey<K> key, CacheValue<V> value);
because, ultimately, all implementations of CacheKey<K> and CacheValue<V> should be indistinguishable.
If you really want to force the CacheKey<K> and CacheValue<V> to be of specific types, you need to add more type variables:
public interface Cache<
K extends Serializable, CK extends CacheKey<K>,
V extends Serializable, CV extends CacheValue<V>> {
void put(CK key, CV value);
}
but this is really quite gross, as you would have to carry around all of these 4 type variables wherever you use a Cache type directly.
Of course, you can specialize the interface to hide some of these type variables:
interface StringKey extends CacheKey<String> {}
interface IntegerValue extends CacheValue<Integer> {}
interface StringIntegerCache extends Cache<String, StringKey, Integer, IntegerValue> {}
and then just use StringIntegerCache. The usefulness of doing so depends on your application.

Related

In an interface, I first declare a generic that extends an interface, then a generic that extends the first generic along with another interface

For example,
public interface Foo<T extends Blackness, S extends T & Whiteness> { }
Error: Type parameter cannot be followed by other bounds
T extends Blackness and S extends T so S inherently extends Blackness. The only other contingency is that S must also extends Whiteness. Because of this restriction, S must be an extension of T but also implement the functionality of Whiteness. Because of this, you will likely have to provide the type T. It's not possible for S to have multiple bounded types, which is why a sub-interface is required that implements both. What you're trying to do doesn't make logical sense. Refer to this.
public interface Foo<T extends Blackness, S extends BlackAndWhiteness<T>> {
}
public interface BlackAndWhiteness<T extends Blackness> extends Whiteness, Blackness {
}
interface Blackness {
}
interface Whiteness {
}

Java : generic type with type parameters?

I have a class like this :
public class MyClass <T extends Model1, X extends Model2> {
private CommonMessage<T,X> someMethod() {
....
}
}
Now I have a customized message type MyMessage extends CommonMessage, so I want to know how to have generic type that still having T and X as parameters ? For example :
public class MyClass <M extends CommonMessage, T extends Model1, X extends Model2> {
private M<T,X> someMethod() {
....
}
}
Short answer:
First of all as CommonMessage is generic, extending it in a non-generic way is very bad so you should have done M extends CommonMessage<T, X> And this way because type parameter passed to CommonMessage at class declaration you should not mention this parameter type again at method return type so method return type should be M.
Long answer:
I know you do know this definitions but sometimes we as human forget simple things. First we should consider what generics are created for, with generics we can create classes with different parameter types, this parameter types will be provided when they are extended by another class or when we create new instance of them with new() operator, so when we are writing our class we don't know the exact type for those parameter and we want to delay this decision until later, it is contradictory to something you are doing in your class because here your method is private and you can't change its implementation in your child class(the class which inherited from your class). But know we can change your implementation to something like this which will be compiled well:
public class MyClass<M extends CommonMessage<T, X>, T extends Model1, X extends Model2> {
private M method1(){
...
}
}
public class CommonMessage<T, X>{
}
public class MyMessage<T, X> extends CommonMessage<T, X>{
}
public class Model1{
}
public class Model2{
}
although this implementation will be compiled the problem is that when you are writing your private method(method1) you don't know what is the type of M at the time of writing this class because it will be passed when we want to create new instance of this class or when we inherit another class from this class. so what type of Object do you want to create and return in your method1? the only thing that you know here is that its type is M which extends CommonMessage but you don't know what the exact type of M is at the time of writing your private method(method1)!
And on the top of that you can't delegate this decision to your subclass(because this method is private). Now the question is that why it is allowed and compiled well when we don't know the exact type of M? for a moment forget this question I will make it clear after explaining correct approach. so what is the correct approach? Think about it, the person who write subclass does know exactly what the type of parameter M is and they can create appropriate instance of M in implementation of method1 to return from this method. so why not delegate this decision to subclass and making this method abstract? This completely make senses. in a nutshell we have some implementation like this:
public abstract class MyClass<M extends CommonMessage<T, X>, T extends Model1, X extends Model2> {
public abstract M method1();
}
public class CommonMessage<T, X>{
}
public class MyMessage<T, X> extends CommonMessage<T, X>{
}
public class Model1{
}
public class Model2{
}
now lets get back to our question why first program that I suggested to you compiled well? why we are allowed to have private method that its return type is generic that will be passed at instanciation or inheritance time?
because there are a lot of situations that make it correct and appropriate.
one situation is that our private method call another public method which return the appropriate type, like this:
public abstract class MyClass<M extends CommonMessage<T, X>, T extends Model1, X extends Model2> {
private M method1(){
return method2();
}
abstract M method2();
}
public class CommonMessage<T, X>{
}
public class MyMessage<T, X> extends CommonMessage<T, X>{
}
public class Model1{
}
public class Model2{
}

Avoiding cast in generic factory-based MVP framework

I was trying to implement a way to decouple View and Presenter in the MVP pattern to provide a framework, which does exactly this, but after a point I got confused.
Background
I have a View interface with a generic type for the connected presenter and vice versa. Those interfaces are to be extended by the implementing developer. The concrete interface is not of interest for this question, but the class definition of those both look like the following:
public interface Presenter<T extends View>
and
public interface View<T extends Presenter>
The idea is that both the View and the Presenter know the opposing interface.
For using this structure, the developer should provide a factory, that instantiates the View he wants to show and the Presenter that is handling this View. He gives both of them to a class called the SuperController. They are associated by the class of the View.
The PresenterFactory interface, which creates the Presenter, has no parameters and returns a Presenter implementation and looks the following:
public interface PresenterFactory<T extends View> {
<S extends Presenter<T>> S create();
}
The ViewFactory interface, which creates the View, creates a View implementation, based on the Presenter and looks the following:
public interface ViewFactory<T extends View, S extends Presenter<T>> {
T create(S presenter);
}
Problem
The problem I am encountering is the following:
I wanted to provide an example with a TestView and a TestPresenter. Those look like this:
public interface TestPresenter extends Presenter<TestView> {...}
public interface TestView extends View<TestPresenter> {...}
Also, a ViewFactory is provided, which looks like this:
class TestViewFactory implements ViewFactory<TestView, TestPresenter> {
#Override
public TestView create(TestPresenter presenter) {
return new TestViewImpl(presenter);
}
}
And this is the TestPresenterFactory:
private class TestPresenterFactory implements PresenterFactory<TestView> {
#Override
public <S extends Presenter<TestView>> S create() {
return new TestPresenterImpl();
}
}
This code cannot be compiled. The problem is the return value of the TestPresenterFactory. Java says, it expects S and not a TestPresenterImpl. Also, casting to TestPresenter will not work. However, casting to S will work. It than can be compiled and also runs successfully, but this is not what I wanted the implementing developer to do.
Why does this problem exist? And why does casting to the concrete interface not work? In my opinion, this should work, because the TestPresenterImpl implements the TestPresenter, which extends Presenter of the generic type TestView yet it is not compilable.
The following does work. If you change the PresenterFactory definition like this:
public interface PresenterFactory<T extends View, S extends Presenter<T>> {
S create();
}
with the example implementation now looking like this:
private class TestPresenterFactory implements PresenterFactory<TestView, TestPresenter> {
#Override
public TestPresenter create() {
return new TestPresenterImpl();
}
}
It can be compiled and run, just like if I cast to S in the above example.
However, this is not what I want. The generic type declaration is redundant. Letting the implementing developer declare the View and the presenter, to only create the Presenter looks awkward. It would be really great if the type could inferred at the method.
Also, I do not want to force the implementing developer to cast to S.
Is there a more elegant way for this?
edit
A question was brought up as a duplicate and I want to distance myself from this question.
The problem that arises from this has nothing to do with Producer Extends Consumer Super. I have two producers (factories) in use. Both of which are producing a class. One depends on another class (the View depends on the Presenter), while the other one is without dependency (the Presenter can be instantiated with a default constructor). All respected interfaces have the T extends XYZ definition, to allow the production of interfaces, which inherit of that interface (either the Presenter or the View).
The real problem here is that the generic within the ViewFactory can be inferred by Java. Both of the generic types are declared within the class definition. Within the PresenterFactory, the method-level generic cannot be inferred by Java. Even though, the generic type is the same as the one in the view factory <S extends Presenter<T>>; at the method, this type cannot be inferred.
The solution is to either cast (which I don't want the using developer to do) or to declare the PresenterType in the class definition (which seems to be redundant. The only thing of interest is, that the view is defined and any Presenter for that view is returned).
My question is what can I do to work around said issues that are a result of the extends clause?
For starters, this will solve the problem:
interface PresenterFactory<T extends View, S extends Presenter<T>> {
S create();
}
class TestPresenterFactory implements PresenterFactory<TestView, TestPresenterImpl> {
#Override
public TestPresenterImpl create() {
return new TestPresenterImpl();
}
}
But I still don't like:
the circular dependency between View and Presenter;
the use of raw types: actually, if you blindly use View<?> and Presenter<?> in their respective interface declarations, then again it won't compile (TestPresenterFactory will fail).
--- edit ---
So how about this to fix the last 2 points, along with your original issue:
interface Presenter<P extends Presenter<P, V>, V extends View<P, V>> {
}
interface View<P extends Presenter<P, V>, V extends View<P, V>> {
}
interface PresenterFactory<P extends Presenter<P, V>, V extends View<P, V>> {
P create();
}
interface ViewFactory<P extends Presenter<P, V>, V extends View<P, V>> {
V create(P presenter);
}
interface TestPresenter extends Presenter<TestPresenter, TestView> {}
class TestPresenterImpl implements TestPresenter {
}
interface TestView extends View<TestPresenter, TestView> {}
class TestViewImpl implements TestView {
public TestViewImpl(Presenter<?, ?> presenter) {
}
}
class TestViewFactory implements ViewFactory<TestPresenter, TestView> {
#Override
public TestView create(TestPresenter presenter) {
return new TestViewImpl(presenter);
}
}
class TestPresenterFactory implements PresenterFactory<TestPresenter, TestView> {
#Override
public TestPresenter create() {
return new TestPresenterImpl();
}
}

Is there a way of specifying a nested generic without specifying a type twice in Java 8+

Given the following example...
S denotes a start Node of ConcreteType A
T denotes a end Node of ConcreteType B
E denotes an Edge with S as start Node and T as end Node
EdgeSet has a set of Edges accessed by an interface methods
SomeObject o returns an EdgeSet interface via a method SomeObject.getEdges();
A class definition defined using generics as follows...
public class EdgeSet<S extends Node, T extends Node, E extends Edge<S, T>> { ... }
public class SomeObject {
protected EdgeSet<ConcreteNodeA, ConcreteNodeB, ConcreteEdge<ConcreteNodeA, ConcreteNodeB>> someEdgeSet;
...
public EdgeSet<? extends ConcreteNodeA, ? extends ConcreteNodeB, ? extends ConcreteEdge<? extends ConcreteNodeA, ? extends ConcreteNodeB>> getEdges() {
//returns someEdgeSet...
}
}
Usage Example...
EdgeSet<? extends ConcreteNodeA, ? extends ConcreteNodeB, ? extends ConcreteEdge<? extends ConcreteNodeA, ? extends ConcreteNodeB>> exampleEdgeSet = o.getEdges();
Is there some way of defining this code, and the code which uses the member method without defining things twice?
For example:
public class EdgeSet<E extends Edge<S extends Node, T extends Node>> { ... }
EdgeSet<ConcreteEdge<? extends ConcreteNodeA, ? extends ConcreteNodeB>>
protected EdgeSet<ConcreteEdge<ConcreteNodeA, ConcreteNodeB>>
If not, is there somewhere where you can put through an RFC to reduce redundant information?
Is there some way of defining this code, and the code which uses the member method without defining things twice?
Given your EdgeSet as you currently define it, the only alternative I see is to use an Edge implementation that is non-generic:
public class ConcreteEdgeAB extends Edge<ConcreteNodeA, ConcreteNodeB> {
// ...
}
Then you could write declarations such as
protected EdgeSet<ConcreteNodeA, ConcreteNodeB, ConcreteEdgeAB> someEdgeSet;
That still has some redundancy, however, because ConcreteNodeA and ConcreteNodeB are the only types you can use for S and T when you use ConcreteEdgeAB as E. Moreover, it's not as flexible is you would probably like.
I'm inclined to think that the main problem is that you have over-parameterized. If your Edge type is itself parameterized by the node types of its ends, then it is inherently redundant to parameterize a set of edges on the node types as well -- an edge set should need only to be parameterized on the type of edges it contains:
interface Edge<S extends Node, T extends Node> {
}
// The bounds on the type parameters of Edge effectively apply here, too:
public class EdgeSet <E extends Edge<?, ?>> {
// ...
}
public class SomeObject {
protected EdgeSet<ConcreteEdge<ConcreteNodeA, ConcreteNodeB>> someEdgeSet;
...
public EdgeSet<? extends ConcreteEdge<? extends ConcreteNodeA, ? extends ConcreteNodeB>> getEdges() {
return someEdgeSet;
}
}

Java Interface with Inheritance

I'm looking for assistance on how to implement this Repository. Here's what I have so far:
public interface IEntity {
int getId(); //would rather not depend on int. fix later.
}
public interface IRepository<T extends IEntity> {
Collection<T> findAll();
T find(T t);
T findById(int id); //would rather not depend on int. fix later.
void add(T t);
void remove(T t);
}
public interface ISurveyRepository extends IRepository<Survey> {
}
The problem I'm running into is that I need for T in the IRepository signature to extend IEntity, but I don't need IRepository in the ISurveyRepository signature to have a bounded type parameter. I would like for the signature to just be
public interface ISurveyRepository extends IRepository { }
so that I could create a concrete class that just implements ISurveyRepository
public class MySurveyRepository extends ISurveyRepository { }
How can I go about doing that?
You can do better than this.
Fix that int problem now. Use a generic DAO interface, like this:
public interface Repository<T, K extends Serializable> {
List<T> find();
T find(K id);
K save(T value);
void update(T value);
void delete(T value);
}
Lose that Hungarian notation in disguise: no "I" for "interface".
You can write a generic implementation, too.
If you want to create a class like:
public class MySurveyRepository extends ISurveyRepository {}
Then your existing interface (with the use of generics) will do just fine. Your implementing class will 'inherit' the definition by design, and will be (effecticely) completely unaware that it's descended from a previously-generic interface.
If you're using one of the modern editors, like Eclipse, to write your code, when you ask it to fill in the missing inherited methods it won't give you T - it'll give you Survey.

Categories