在Java中,我构造了一个以String类型为参数的泛型类。在类中,我想访问String类型的方法。但我得到一个错误无法解决符号 - 任何人都看到这个问题:
public final class App
public static void main(String[] args) {
MyClass<String> myClass = new MyClass<String>("some string");
}
}
public class MyClass<T> {
public MyClass(T someString) {
String someSubString = someString.substring(2,3);
}
}
这是一个更新: 我真的使用String作为占位符 - 我真正想做的是:
public final class App
public static void main(String[] args) {
MyClass<SpecificType2> myClass = new MyClass<SpecificType2>();
}
}
public class GeneralType {
public methodOfSpecificType() {...}
}
public class SpecificType1 extends GeneralType {
@Override
public methodOfSpecificType() {...}
}
public class SpecificType2 extends GeneralType {
@Override
public methodOfSpecificType() {...}
}
public class MyClass<T> {
public MyClass(T specificType) {
specificType.methodOfSpecificType();
}
}
答案 0 :(得分:3)
根据您的示例,所有编译器都知道,T
是Object
。 substring(int,int)
不是属于Object
类的方法,因此无法保证substring
将存在,因此无法编译。
如果您希望能够在此处访问substring
,那么泛型确实不适用于此解决方案。您应该T
作为String
。只有在需要通用功能时才使用泛型。
额外阅读
答案 1 :(得分:0)
如果您总是在构造函数中收到一个字符串,则必须将该参数声明为字符串:
public class MyClass<T> {
public MyClass(String someString) {
String someSubString = someString.substring(2,3);
}
}
答案 2 :(得分:0)
您创建了一个泛型类,以便为您将用于它的每种基类型编写一个应该相同的行为。
例如,如果您编写一个类似List<T>
的容器,其中包含添加,删除等方法,那么它应该对List<String>
或List<Integer>
或List<SomeUserClassIDontKnowAbout>
。
如果您编写的类行为仅适用于某种类型的对象(如字符串),则不适合将其写为泛型,因为它是特定的,而不是通用的。 (当然,它可以是一个有界的泛型类型,但是现在不要去那里)。
如果你有一些应该在特定类型上工作的方法(例如接受一个String并将其解析为其他类型),那么可以这样做,但是你必须用特定的类型声明它,而不是使用您的泛型类型变量(T
等)。
如果您发现所有方法都是特定的而不是通用的,并且您最终只在类头中使用了类型变量,那么您正在编写特定的类,而不是通用的类。无需将其声明为通用。
答案 3 :(得分:0)
如果您知道参数可以是预先建立的对象集之一,则可以在运行时使用instanceof
检查实例类型,然后将其强制转换并使用它:
if (specificType instanceof GeneralType) {
GeneralType generalType = (GeneralType) specificType;
generalType.methodOfSpecificType();
}
那应该有用。 但是,您最终会为每种类型实现不同的情况,因此您可能应该考虑使用泛型是否是解决此问题的正确方法。