Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
232 views
in Technique[技术] by (71.8m points)

java - generics and inheritance question

I have three classes:

public abstract class fileHandler<Key extends Object, Value extends Object> {
}    

public A extends fileHandler<String, String[]> {
}

public B extends fileHandler<String, String> {
}

Now in my main function i do something like this:

fileHandler file= null;
If (<condition>) {
    fileHandler = new A();
} else
    fileHandler = new B():
}

But this gives 2 compile time errors:

  1. Cannot convert A to fileHandler
  2. Cannot convert B to fileHandler

How can I get rid of these errors as I don't get this error if base class is not generic.

Update:

My class hierarchy is:

  1. class fileHandler<Key, Value> { }
  2. class A extends fileHandler<String, String[]> { }
  3. class B extends fileHandler<String, String> { }
  4. class C that calls function gen(object of A) or
  5. class D that calls function gen(object of B).
  6. both C and D are derived from abstract class E.

Now how should I define these functions in C and D and E:

I gave the following:

E:

public abstract void gen (fileHandler A) throws exception;

C:

void gen (fileHandler A) throws exception;

D:

void gen (fileHandler A) throws exception;

C, D, and E give error fileHandler is raw type. Reference to generic type fileHandler(Key, Value) should be parameterized.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

When you instantiate a generic type with different type arguments, the two instantiations are not type compatible. Different instantiations of a generic type are not type-equivalent in the way that a class that inherits from another class is type-equivalent to that class, even when the type arguments themselves may be related by inheritance. Genericity and polymorphism are two separate language features.

Your code is equivalent to the following:

// Java defaults unspecified type arguments to Object.
fileHandler<Object, Object> file;

if (...) {
   // Error: fileHandler<String, String> is not equivalent to fileHandler<Object, Object>
   file = new fileHandler<String, String>();
} else {
   // Error: fileHandler<String, String[]> is not equivalent to fileHandler<Object, Object>
   file = new fileHandler<String, String[]>();
}

If you truly want to isolate a polymorphic interface that is independent of the types used to instantiate your fileHandler class, then I would suggest you use an interface:

interface IFileHandler
{
    // If this interface needs to talk about keys and values, it
    // does so using only java.lang.Object.
}

public class fileHandler<Key extends Object, Value extends Object>
    implements IFileHandler
{
    // ...
}

public class A extends fileHandler<String, String>
{
    // ...
}

public class B extends fileHandler<String, String[]>
{
    // ...
}

IFileHandler file;

if (...) {
    file = new A();
} else {
    file = new B();
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...