(使用Java)我正在实现一个B-Tree的泛型类。当用户运行程序时,他们可以提供一些参数来确定树的类型(整数,字符,双精度或字符串)。
在我的主要方法中,我有这段代码:
// Get user input and split it into tokens
// Tokens[1] = the type specified by the user
if( tokens[1].equals("DOUBLE"))
BTree<Double> t = new BTree<Double>();
else if( tokens[1].equals("CHARACTER"))
BTree<Character> t = new BTree<Character>();
else if( tokens[1].equals("INTEGER"))
BTree<Integer> t = new BTree<Integer>();
else if( tokens[1].equals("STRING"))
BTree<String> t = new BTree<String>();
但编译器抱怨我是否有if语句。如果我删除它然后编译并运行良好:/我该如何解决这个问题?这样用户可以提供类型,树将根据提供的类型创建?感谢。
以下是一些编译器输出:
C:\Users\User\Desktop>javac *.java
Main.java:42: error: cannot find symbol
BTree<Double> t = new BTree<Double>();
symbol: variable BTree
location: class Main
Main.java:42: error: cannot find symbol
BTree<Double> t = new BTree<Double>();
symbol: variable Double
location: class Main
Main.java:42: error: cannot find symbol
BTree<Double> t = new BTree<Double>();
symbol: variable t
location: class Main
..还有更多,但它类似,并为每种类型重复
答案 0 :(得分:1)
每个t
语句中的变量if
仅在if
的上下文中定义,在它们之外,编译器将无法识别它们。
在t
语句之前定义变量if
。
BTree<?> t = null;
if( tokens[1].equals("DOUBLE")) {
t = new BTree<Double>();
}
else if( tokens[1].equals("CHARACTER")) {
t = new BTree<Character>();
}
else if( tokens[1].equals("INTEGER")) {
t = new BTree<Integer>();
}
else if( tokens[1].equals("STRING")) {
t = new BTree<String>();
}
// now you can use your 't'
答案 1 :(得分:1)
您的BTree<T>
类不应该是抽象的,因为您似乎想要为所有类型T
实现相同的功能。
如果您需要针对不同类型T
的特定功能,则需要实施
class CharacterBTree extends BTree<Character>
或者像
一样动起来 BTree<Character> t = new BTree<Character>() {
...
};
也;在if之外声明您的BTree<T> t
变量,因此您的代码变为
BTree<?> t = null;
if ("char".equals(whatever)) {
t = new BTree<Character>();
} else if {
...
}
答案 2 :(得分:0)
插入大括号:
if( tokens[1].equals("DOUBLE")){
BTree<Double> t = new BTree<Double>();
}
else if( tokens[1].equals("CHARACTER")){
BTree<Character> t = new BTree<Character>();
}
else if( tokens[1].equals("INTEGER")){
BTree<Integer> t = new BTree<Integer>();
}
else if( tokens[1].equals("STRING")){
BTree<String> t = new BTree<String>();
}
或者在声明之前声明你的树:
BTree<? extends Object> t = null;
if( tokens[1].equals("DOUBLE"))
t = new BTree<Double>();
else if( tokens[1].equals("CHARACTER"))
t = new BTree<Character>();
else if( tokens[1].equals("INTEGER"))
t = new BTree<Integer>();
else if( tokens[1].equals("STRING"))
t = new BTree<String>();
答案 3 :(得分:0)
我会使用case-switch语句(也许它不是你需要的解决方案,因为错误的操作说,看到日志可以帮助更多一点)从逻辑的角度来看:
switch(tokens[1]) {
case "DOUBLE" : BTree<Double> t = new BTree<Double>(); break;
....
....
}
答案 4 :(得分:0)
如果您正在尝试类似
的内容if (tokens[1].equals("DOUBLE"))
BTree<Double> t = new BTree<Double>();
else if (tokens[1].equals("CHARACTER"))
BTree<Character> t = new BTree<Character>();
// etc.
t.doStuff();
那不行。首先,因为t
变量仅在其if
语句中的范围内,其次,因为您不能使变量在不同的代码路径中具有不同的静态类型。
您可以执行类似
的操作BTree<?> t;
if (tokens[1].equals("DOUBLE"))
t = new BTree<Double>();
else if (tokens[1].equals("CHARACTER"))
t = new BTree<Character>();
// etc.
但是之后你不能对t
中存储的项目做任何有用的事情,因为后面的代码不知道它是什么树。这更像是一个基本的设计问题,而不是语法问题。
您可以创建一个接口 - 让我们称之为ValueHolder
- 并使用它来定义您需要对树中的值执行的任何操作。然后定义类DoubleHolder
,CharacterHolder
等类,它们实现ValueHolder
接口。然后你可以写:
BTree<? extends ValueHolder> t;
if (tokens[1].equals("DOUBLE"))
t = new BTree<DoubleHolder>();
else if (tokens[1].equals("CHARACTER"))
t = new BTree<CharacterHolder>();
// etc.
之后,您可以从树中检索项目,它们的类型为ValueHolder
,因此您可以调用该界面提供的任何方法。