An error was reported when the find method was called.
interface Node<N extends Node<N>> {
void setNext(N next);
N getNext();
}
interface Entry<K, V> extends Node<Entry<K, V>> {
K getKey();
void setValue(V value);
V getValue();
}
class Test {
public static <N extends Node<N>> N find(N base, Object obj) {
for (N node = base; node != null; node = node.getNext())
if (node.equals(obj))
return node;
return null;
}
public static <K, V, E extends Entry<K, V>> E getEntry(E[] table, K key) {
return find(table[0], key);
}
}
Bound mismatch: The generic method find(N, Object) of type Test is not applicable for the arguments (E, K). The inferred type E is not a valid substitute for the bounded parameter >
I do not know why this is so.
答案 0 :(得分:4)
问题在于:
interface Node<N extends Node<N>> {
void setNext(N next);
N getNext();
}
interface Entry<K, V> extends Node<Entry<K, V>> {
K getKey();
void setValue(V value);
V getValue();
}
你有E extends Entry<E, V>
。 E.getNext()
返回什么?由于Entry<K, V> extends Node<Entry<K, V>>
,E.getNext()
至少返回Entry<K, V>
,这是肯定的。
但它会E
吗? Entry<K, V>.getNext()
仅保证返回Entry<K, V>
的某个实例。但不能保证返回与Entry<K, V>
实际上完全相同的类型。代码中没有任何内容强制E.getNext()
返回E
,只有某些实例分配兼容Entry<K, V>
。
因此,对find
方法推断的最佳方法是Entry<K, V>
,E
不一定与/* This program assumes that
names and IDs data file (location and name) is passed as the first argument
and marks data files is passed as the second argument
*/
#define MAXRECORDS 100
#define MAXNAMELENGTH 15
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//Define structure to hold student data
struct StudentRecord
{
char FirstNames[MAXNAMELENGTH];
char LastNames[MAXNAMELENGTH];
int IDNums;
int Marks;
};
int main(int argc, char * argv[]) {
struct StudentRecord SRecords[MAXRECORDS];
int numrecords, nummarks, recordnum, r;
char Temp[1];
//Read in Names and ID data
FILE * NamesIDsDataFile;
if((NamesIDsDataFile = fopen(argv[1], "r")) == NULL){
printf("Can't read from file %s\n", argv[1]);
exit(1);
}
numrecords=0;
while (fscanf(NamesIDsDataFile,"%s%s%d",&(SRecords[numrecords].FirstNames[0]),
&(SRecords[numrecords].LastNames[0]),
&(SRecords[numrecords].IDNums)) != EOF) {
numrecords++;
}
fclose(NamesIDsDataFile);
//Read in marks data
FILE * MarksDataFile;
if((MarksDataFile = fopen(argv[2], "r")) == NULL){
printf("Can't read from file %s\n", argv[2]);
exit(1);
}
nummarks=0;
while(fscanf(MarksDataFile,"%d",&(SRecords[nummarks].Marks)) != EOF) {
nummarks++;
}
fclose(MarksDataFile);
//Print out data as read in
for(recordnum=0;recordnum<numrecords;recordnum++){
printf("%s %s %d %d\n",SRecords[recordnum].FirstNames,SRecords[recordnum].LastNames,SRecords[recordnum].IDNums, SRecords[recordnum].Marks);
}
printf("A total of %d records printed.\n",numrecords);
while (recordnum>0){
numrecords=0;
while (SRecords[numrecords].LastNames[0] != EOF ){
r= strcmp(SRecords[numrecords].LastNames, SRecords[numrecords+1].LastNames);
if (r>0){
strcpy(Temp, SRecords[numrecords].LastNames);
strcpy(SRecords[numrecords].LastNames, SRecords[numrecords+1].LastNames);
strcpy(SRecords[numrecords+1].LastNames, Temp);
}
numrecords++;
}
recordnum--;
}
printf("\nTHE SORTED NAMES ARE AS FOLLOWS\n");
for(recordnum=0;recordnum<numrecords;recordnum++){
printf("%s %s %d %d\n",SRecords[recordnum].FirstNames,SRecords[recordnum].LastNames,SRecords[recordnum].IDNums, SRecords[recordnum].Marks);
}
printf("A total of %d records printed.\n",numrecords);
return EXIT_SUCCESS;
}
兼容。
答案 1 :(得分:2)
我们知道
Entry<K, V> extends Node<Entry<K, V>>
和
E extends Node<Entry<K, V>>
这两件事共同意味着
find
但是,为了使E extends Node<E>
方法适用,我们需要
E
但这不符合,因为Entry<K, V>
只是Node
的子类型,不等于它。
问题是虽然N
有一个表示其自己的具体实现类型(Entry
)的类型参数,但interface Entry<K, V, E extends Entry<K, V, E>> extends Node<E> {
K getKey();
void setValue(V value);
V getValue();
}
public static <K, V, E extends Entry<K, V, E>> E getEntry(E[] table, K key) {
return find(table[0], key);
}
却没有。您可以通过为此目的添加第三个类型参数来修复它。
ES6