Bound mismatch: The type Integer is not a valid substitute for the bounded parameter <Item extends Comparable<Item>> of the type BTNode<Item>
This is where I am getting the error:
public class BinaryTree<Integer> {
private BTNode<Integer> root;
//...
}
This is the class I am using:
public class BTNode<Item extends java.lang.Comparable<Item>> implements java.lang.Comparable<BTNode<Item>> {
private Item data;
//...
}
I think the Integer wrapper should satisfy the condition <xx extends Comparable<xx>>.
Is my understanding wrong? Can you please tell me what I am doing wrong here?
Just for the record, I am using java.lang.Comparable and not my own implementation of Comparable.
Here is the issue:
public class BinaryTree<Integer> {
private BTNode<Integer> root;
}
The class parameter is named Integer. When declaring BTNode<Integer>, you are not referencing java.lang.Integer but the parameter instead.
I don't really know what you're trying to do, but one advice: better use one single letter to name your classes parameters. For example, no error occurs when using:
public class BinaryTree<T> {
private BTNode<Integer> root;
}
If you wanted root to really use the class parameter, then:
public class BinaryTree<T extends Comparable<T>> {
private BTNode<T> root;
}
Have a look at the following lesson: http://docs.oracle.com/javase/tutorial/extra/generics/index.html
Related
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>>{
I am building a generic binary tree class in Java. I have not worked with generics too much before, so I do not know if I am doing this properly. Here is some code followed by my question:
public class Node<T> {
T data;
Node<T> left, right;
//assume setters and getters
}
public class BinaryTree<T extends Comparable <T>> {
private Node<T> root;
//assume typical setter/getter and insert, delete, etc methods
public void inOrderTraversal() {
//create instance of the inorder class here and call its traverse() method.
}
}
//define a family of algorithms for preorder, inorder and postorder traversals
public interface BinaryTreeTraversal {
public void traverse();
}
//of course there will be a class for each type of traversal...
//in order, pre order, post order
class PreOrderTraversal extends BinaryTree implements BinaryTreeTraversal {
public void traverse() { traverse(super.getRoot() ); }
private void traverse(Node<T>) {
//the three lines of code this takes
}
}
So the problem I am having is that I keep getting errors saying missing type T, or unknown type T. So I tried changing the class heading it to
class PreOrderTraversal extends BinaryTree<T> implements BinaryTreeTraversal { }
and
class PreOrderTraversal extends BinaryTree<T extends Comparable<T>> implements BinaryTreeTraversal { }
and it did not work due to similar errors. What is a way that I can make this work? I am trying to apply a strategy pattern to the traversals. I just want to be able to have three types of traversals for any generic type. Any tips would be appreciated. Thank you.
private class PreOrderTraversal< T extends Comparable< T > > extends BinaryTree< T > implements BinaryTreeTraversal { ... }
For generic classes, the parameter and all its constraints go right next to the name of the class being defined. Unfortunately, that syntax was not chosen for generic methods, where the generic type parameters and constraints precede the return type.
your class PreOrderTraversal implements you generic class BinaryTree so here you need to define the type of T like
java
class PreOrderTraversal extends BinaryTree<Integer> implements BinaryTreeTraversal {
private void traverse(Node<Integer>) {
}
}
where Integer would by the type you are storing in the binary tree, now
public class ChampionsLeague<Team extends Comparable<Team>> extends League<Team>{
...
How do I make an instance of this class?
ChampionsLeague<Team> league = new ChampionsLeague<>();
This does not work:
"Bound mismatch: The type Team is not a valid substitute for the bounded parameter <Team extends Comparable<Team>> of the type ChampionsLeague<Team>"
In your code, Team is just a placeholder (in this context, called Type Variable) and happens to be hiding the type Team, not referencing it. In other words, that declaration is equivalent to:
public class ChampionsLeague<T extends Comparable<T>> extends League<T> {
So it is really only asking for a class (or interface) that implements (extends) Comparable of itself. So this example:
public class Ball implements Comparable<Ball> {
#Override
public int compareTo(Ball o) { return 0; }
}
// or: public interface Ball extends Comparable<Ball> { }
Will work:
ChampionsLeague<Ball> test = new ChampionsLeague<Ball>();
Edit:
Some possibilities to what you may be trying to achieve:
// ChampionsLeague needs a type Comparable to Team
public class ChampionsLeague<T extends Comparable<Team>> extends League<T> {
or
// ChampionsLeague needs a subtype of Team
// In this case, you can make Team implement Comparable<Team> in its own decl.
public class ChampionsLeague<T extends Team> extends League<T> {
I would like to declare attribute that holds instance of class that implements 2 different interfaces. I have tried this syntax:
private <? extends Interface1 & Interface2> name;
and this:
private <T extends Interface1 & Interface2> T name;
None of those work. Is it possible? What's the syntax? I'm trying to avoid declaring another interface that inherits from both Interface1 and Interface2.
Edit:
The class containing this attribute should not have any type arguments. That is nothing like this:
public class MyClass<T extends Interface1 & Interface2>{
private T name;
...
}
It would not make any sense for those using the class. It is not expected neither logical not possible for that class to be generic.
That needs to go in the class declaration, such as:
public class TestG<T extends Cloneable & Serializable> {
private T name;
}
One alternative is to set it in a method (but not a variable)
public class TestG {
public <T extends Cloneable & Serializable> void method(T parameter) {
}
}
A variable cannot be generic.
private <T> T var;
is not possible - at which point is T defined? When accessing var, I cannot make much assumptions on what I used at assignment time.
Java allows generics on classes and on methods. So you can have
private <T implements Cloneable & Serializable> void setVar(T val);
and you can have a class-wide type T.
But always remember that in the end, it is implemented by type erasure. You can always emulate more complex logic using getters, setters and casts. When done properly, it will give you just as much type safety.
The simplest way to obtain a variable with the type safety you want is to just use two variables, and a setter to keep them in sync.
private Serializable vars;
private Cloneable vars;
will of course give you a good type safety. But yes, it needs 4 bytes of additional memory, and a setter.
Here's the casting approach you asked:
private Object internal_var;
// Implementation notice: do not remove this generic.
// Due to a Java limitation, we *do* want these two constraints!
public <T extends Serializable & Cloneable> void setVar(T val) {
internal_var = val;
}
public Serializable getSerializable() {
return (Serializable) internal_var; // Type checked in setter!
}
public Cloneable getCloneable() {
return (Cloneable) internal_var; // Type checked in setter!
}
// This is the way to use it in a generic getter:
public <T extends Serializable & Cloneable> T getVar(Class<? super T> cls) {
return (T) cls.cast(val);
}
Note that in order to use T in the getter, we do need to have a parameter involving T.
Assuming we know a class Example implements Serializable, Cloneable, we can then use
// This actually ensures we get an instance of `Example` out:
Example e = instance.getVar(Example.class);
You can declare that type parameter in your class declaration, or method declaration, if that is a local variable, and use that type instead: -
public class Demo<T extends Interface1 & Interface2> {
private T t;
}
or: -
public class Demo {
public <S extends Interface1 & Interface2> void demo(S param1) {
S param;
}
}
If i understand your question correctly, you want a generic class which implements both the inetrfaces.
declare a generic type argument in your class definition and make it as an instace variable type.
public class Implementor<T extends Interface1<T> & Interface2<T>> {
private T t;
}
EDIT:
you cannot declare a type argument at instance variable declaration like
private <T extends I1 &I2> T t; //this cant be achieved.
at method level though is possible.
public <T extends I1 & I2> void method(T t){
}
I have the concept of NodeTypes and Nodes. A NodeType is a bunch of meta-data which you can create Node instances from (a lot like the whole Class / Object relationship).
I have various NodeType implementations and various Node implementations.
In my AbstractNodeType (top level for NodeTypes) I have ab abstract createInstance() method that will, once implemented by the subclass, creates the correct Node instance:
public abstract class AbstractNodeType {
// ..
public abstract <T extends AbstractNode> T createInstance();
}
In my NodeType implementations I implement the method like this:
public class ThingType {
// ..
public Thing createInstance() {
return new Thing(/* .. */);
}
}
// FYI
public class Thing extends AbstractNode { /* .. */ }
This is all well and good, but public Thing createInstance() creates a warning about type safety. Specifically:
Type safety: The return type Thing for
createInstance() from the type
ThingType needs unchecked conversion
to conform to T from the type
AbstractNodeType
What am I doing wrong to cause such a warning?
How can I re-factor my code to fix this?
#SuppressWarnings("unchecked") is not good, I wish to fix this by coding it correctly, not ignoring the problem!
You can just replace <T extends AbstractNode> T with AbstractNode thanks to the magic of covariant returns. Java 5 added support, but it didn't receive the pub it deserved.
Two ways:
(a) Don't use generics. It's probably not necessary in this case. (Although that depends on the code you havn't shown.)
(b) Generify AbstractNodeType as follows:
public abstract class AbstractNodeType<T extends AbstractNode> {
public abstract T createInstance();
}
public class ThingType<Thing> {
public Thing createInstance() {
return new Thing(...);
}
}
Something like that should work:
interface Node{
}
interface NodeType<T extends Node>{
T createInstance();
}
class Thing implements Node{}
class ThingType implements NodeType<Thing>{
public Thing createInstance() {
return new Thing();
}
}
class UberThing extends Thing{}
class UberThingType extends ThingType{
#Override
public UberThing createInstance() {
return new UberThing();
}
}