My question is a generic syntax question. As answered in this thread, I created the abstract generic super class.
public abstract class Translator <T extends OriginalText, V extends LanguageTranslation> {
public abstract V translate(T originalText);
}
Now, I fail in defining the child class.
public class ChineseToEnglishTranslator extends Translator<ChineseText, EnglishTranslation> {
#Override
public EnglishTranslation translate(ChineseText text) {
return null;
}
}
Eclipse returns the error: Bound mismatch: The type ChineseText is not a valid substitute for the bounded parameter <T extends OriginalText> of the type Translator<T,V>. ChineseText is definitely a child class of OriginalText. What is the syntax of what I want to do?
Make sure ChineseText extends OriginalText.
I'm not getting any errors as you have said if ChineseText extends OriginalText.
Bound mismatch: The type ChineseText is not a valid substitute for the
bounded parameter of the type
Translator.
This error appears only when ChineseText doesn't extends OriginalText.
Since ChineseText is child of OriginalText and EnglishTranslation is child of LanguageTranslation, the Translator class that uses wildcard extends allows to all classes <? extends OriginalText> to use Translator. By the same way for LanguageTranslation
EnglishTranslation
public class EnglishTranslation extends LanguageTranslation{
}
ChineseText
public class ChineseText extends OriginalText{
}
OriginalText
public class OriginalText {
}
LanguageTranslation
public class LanguageTranslation {
}
ChineseToEnglishTranslator
public class ChineseToEnglishTranslator extends Translator<ChineseText, EnglishTranslation> {
#Override
public EnglishTranslation translate(ChineseText originalText) {
return null;
}
}
Related
I have following class:
public class AClass<T extends XYZClass> extends BFunction<DTOClass, T>{
#Override
public <T extends XYZClass> T apply(DTOClass input) {
return null;
}
}
where T is generic Type, BFunction is function that implements com.google.common.base.Function with apply method. The problem is that this class declaration construction is invalid, because it corresponds following apply method:
#Override
public T apply(DTOClass input) {
return null;
}
I also tried:
public class AClass extends BFunction<DTOClass, <T extends XYZClass> T>{
#Override
public <T extends XYZClass> T apply(DTOClass input) {
return null;
}
}
but this syntax is invalid.
Could you advise me how to correct my class declaration?
Remove the type variable declared on the method:
public class AClass<T extends XYZClass> extends BFunction<DTOClass, T>{
#Override
public /* remove this */ T apply(DTOClass input) {
return null;
}
}
You're trying to declare another type variable called T which hides the type variable declared on the class.
You are declaring a generic method in your parent class, where the <T extends XYZClass> clause has nothing to do with the <T extends XYZClass> in your class declaration.
What you likely want to do is remove <T extends XYZClass> from your method declaration and overrides altogether.
Can someone help me with an explanation as to why this is a type mismatch?
public interface ResponseContainer<T extends ResponsePayload<T>> {
public T getResponsePayload();
}
public interface ResponsePayload<T> {
public T getPayload();
}
protected abstract <T> Class<? extends ResponseContainer<? extends ResponsePayload<T>>> getResponseClazz(Class<? extends ResponsePayload<T>> responseClazz);
And to call it:
private void tryThis() {
ResponseContainer<AccountsResponse> contaner = getResponseClazz(AccountsResponse.class);
}
Gives the compilation error:
Type mismatch: cannot convert from Class<capture#22-of ? extends ResponseContainer<? extends ResponsePayload<AccountsResponse>>> to ResponseContainer<AccountsResponse>
Is this because I can't syntactically use ? extends T when something is implementing it rather than extending it?
You need to change the return type of getResponseClazz. You also should change your generic definition to avoid wildcards. The signature should be
protected abstract <T extends ResponsePayload<T>> ResponseContainer<T> getResponseContainer(Class<T> responseClazz);
EDIT Thanks to Thilo, method name changed
I have a base interface that is parameterized using a type R extending the same base interface :
public interface IWidget<R extends IWidget<R>> {}
Then another interface is parameterized the same way :
public interface IWidgetManager<R extends IWidget<R>> {}
Finally, a class implements the second interface. This class will receive the IWidget implementation class when it will be declared :
public class MyWidgetManager<R extends IWidget<R>> implements IWidgetManager<R> {}
My question :
What is the more specific type that we can use to specify MyWidgetManager?
Class<?> works, of course :
public Class<?> ok() {
return MyWidgetManager.class;
}
But it is very generic and I'd like something more specific...
Those attempts don't compile:
public Class<? extends IWidgetManager<?>> fails() {
return MyWidgetManager.class;
}
==> Type mismatch: cannot convert from Class<MyWidgetManager> to Class<? extends IWidgetManager<?>>
public <R extends IWidget<?>> Class<? extends IWidgetManager<R>> fails() {
return MyWidgetManager.class;
}
==> Type mismatch: cannot convert from Class<MyWidgetManager> to Class<? extends IWidgetManager<R>>
public <R extends IWidget<R>> Class<? extends IWidgetManager<R>> fails() {
return MyWidgetManager.class;
}
==> Type mismatch: cannot convert from Class<MyWidgetManager> to Class<? extends IWidgetManager<R>>
public Class<? extends IWidgetManager<? extends IWidget<?>>> fails() {
return MyWidgetManager.class;
}
==> Type mismatch: cannot convert from Class<MyWidgetManager> to Class<? extends IWidgetManager<? extends IWidget<?>>>
Is there any way I can get a type more specific than Class<?> for MyWidgetManager.class?
UPDATE :
I changed the name of my interfaces. The final class is not a Widget itself, which wasn't clear in my original question... Sorry for the confusion.
UPDATE 2 :
Things are way easier when using concrete types, indeed.
This is really specific to my current situation, but I think I'll fix my "problem" by transforming MyWidgetManager<R extends IWidget<R>> implements IWidgetManager<R> into a WidgetManagerBase that doesn't implement anything. Then provide a default implementation with a concrete Widget class. Finally, the get method could be overriden easily (which is my main goal from the start, by the way!). So :
public interface IWidget<R extends IWidget<?>> {}
public interface IWidgetManager<R extends IWidget<R>> {}
public class WidgetManagerBase {}
// Default implementation
public class WidgetA implements IWidget<WidgetA> {}
public class AWidgetManager extends WidgetManagerBase implements IWidgetManager<WidgetA> {}
// default get method
public Class<? extends IWidgetManager<?>> getWidgetManagerClass() {
return AWidgetManager.class;
}
// The default get method then can be overriden with :
public class WidgetB implements IWidget<WidgetB> {}
public class BWidgetManager extends WidgetManagerBase implements IWidgetManager<WidgetB> {}
#Override
public Class<? extends IWidgetManager<?>> getWidgetManagerClass() {
return BWidgetManager.class;
}
Because of Java Type Erasure the most specific match for MyWidget.class is Class<? extends IWidget>:
public Class<? extends IWidget> test() {
return MyWidget.class;
}
If you want to be even more specific than you should extend MyWidget with concrete type parameters:
public class ConcreteBaseWidget implements IBaseWidget<ConcreteBaseWidget> {
}
public class ConcreteWidget extends MyWidget<ConcreteBaseWidget> {
}
And then all these methods will work:
public Class<? extends IWidget<? extends IBaseWidget<? extends IBaseWidget<?>>>> test1() {
return ConcreteWidget.class;
}
public Class<? extends IWidget<? extends IBaseWidget<ConcreteBaseWidget>>> test2() {
return ConcreteWidget.class;
}
public Class<? extends IWidget<? extends ConcreteBaseWidget>> test3() {
return ConcreteWidget.class;
}
I really think you're just looking for
public interface IBaseWidget<R extends IBaseWidget<R>> {}
and
public interface IWidget<R extends IWidget<R>> extends IBaseWidget<R> {} //not sure about this one.
and
public class MyWidget implements IWidget<MyWidget> {}
That way you can see MyWidget.class as Class<R>.
Is this what you are looking for, or do I misinterpret your intentions?
EDIT:
In that case,
public interface IWidgetManager<R extends IWidget<R>> {}
public class MyWidgetManager<R extends IWidget<R>> implements IWidgetManager<R> {}
could be replaced with
public interface IWidgetManager<R extends IWidget<R>, WM extends IWidgetManager<R, WM>> {}
public class MyWidgetManager<R extends IWidget<R>> implements IWidgetManager<R, MyWidgetManager> {}
because then you will be able to access MyWidgetManager.class as Class<WM>.
My current abstraction model does not work. I am not sure why and how should I fix it. Please refer the following classes.
public class ErrorCaptchaRequired extends AbstractError {
public String getCaptchaUrl(){
return this.captchaUrl;
}
}
public abstract class AbstractError<E extends AbstractError> {
public E getError(int errorCode){
if(error_code == 1)
return new ErrorCaptchaRequired("abc", "abc", "abc");
if(error_code == 2)
return new AnotherErrorType();
}
}
public class MyObject<E extends AbstractError>{
private E error;
public E getAbstractError(){
return error;
}
}
Later on I want to use it like this:
AbstractError<ErrorCaptchRequired> myError = myObject.getAbstractError();
String captchaUrl = myError.getCaptchaUrl();
Compilation error during return statement: Incompatible types But I am not sure why, as in my understanding since I've parametirized class I can return any type which extends from AbstractError and ErrorCaptchaRequired is extending it. Could you please suggest a fix or better design? Thanks for any help!
The problem is raw (untyped) types. Raw types have all generic info stripped from them - hence no type match.
The type of AbstractError is itself raw: Change:
public abstract class AbstractError<E extends AbstractError> {
To
public abstract class AbstractError<E extends AbstractError<E>> {
Next, ErrorCaptchaRequired extends the raw (untyped) form of AbstractError, so every instance of ErrorCaptchaRequired is then raw.
Change:
public class ErrorCaptchaRequired extends AbstractError {
To:
public class ErrorCaptchaRequired<E extends AbstractError<E>> extends AbstractError<E> {
And change:
public class MyObject<E extends AbstractError>{
To:
public class MyObject<E extends AbstractError<E>>{
public class TowerOfHanoi<E> {
private class Disk<T extends Comparable<E>> {
}
private class Peg<S extends Disk<T extends Comparable<E>>> extends Stack<Disk<T extends Comparable<E>>> {
}
}
With the above code, I'm getting the following compilation error.
Syntax error on token "extends", , expected
However, if I change the definition of Peg as follows, it works:
private class Peg<T extends Disk<? extends Comparable<E>>> extends Stack<Disk<? extends Comparable<E>>> {
}
I don't want to use a wildcard. Is there a way to change that to a named parameter?
You can't use generics like that. Simply pass the type (not the bound) to the extended type.
This compiles:
public class TowerOfHanoi<E> {
private class Disk<T extends Comparable<E>> {
}
private class Peg<T extends Disk<Comparable<E>>> extends Stack<Disk<Comparable<E>>> {
}
}
Is there any reason why you can't make E comparable?
public class TowerOfHanoi<E extends Comparable<? super E>>
{
private class Disk implements Comparable<Disk> { }
private class Peg extends Stack<Disk> { }
}