Java 泛型,方法 base() 未为类型 T 定义
Java generics, method base() is undefined for the type T
我正在尝试理解 java 中的泛型,并尝试这个简单的示例,但无法使其工作;它返回错误
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The method base() is undefined for the type T
at javaTest.Main.testShape(Main.java:21)
at javaTest.Main.main(Main.java:25)
下面是代码
class Shape{
int id=1;
void base(){
System.out.println("Shape.base()");
}
}
// unrelated class, but same func name
class OtherShape{
float id=1.1f;
void base(){
System.out.println("OtherShape.base()");
}
}
public class Main {
static <T>void testShape(T shape){
shape.base();
}
public static void main(String[] args) {
testShape(new Shape() );
testShape(new OtherShape());
}
}
关于如何让它发挥作用的任何想法?
我相信您遇到了这个问题,因为您没有将 T 转换为任何对象类型。尝试这样做。
class Shape{
int id=1;
void base(){
System.out.println("Shape.base()");
}
}
// unrelated class, but same func name
class OtherShape extends Shape{
float id=1.1f;
void base(){
System.out.println("OtherShape.base()");
}
}
public class Test {
static void testShape(Shape shape){
shape.base();
}
public static void main(String[] args) {
testShape(new Shape() );
testShape(new OtherShape());
}
}
在 Java 中,泛型是在没有外部上下文的情况下编译的,因此代码必须有效,而不知道最终将如何调用它。
声明某些东西 <T>
意味着您可以传递任何对象,因此 T var
意味着在编译时 var
应该只是 java.lang.Object
。因此 var.base()
没有意义,因为 java.lang.Object
没有提供名为 base()
.
的方法
你可以告诉 T
至少是 Shape
例如通过声明 <T extends Shape>
,然后你可以传递从 Shape
继承的任何东西。但是,您的第二个示例仍然无效,因为 OtherShape
没有继承自 Shape
,即它不满足条件 <T extends Shape>
.
要完全修复它,它应该如下所示:
class Shape{
int id=1;
void base(){
System.out.println("Shape.base()");
}
}
// unrelated class, but same func name
class OtherShape extends Shape{
float id=1.1f;
@Override
void base(){
System.out.println("OtherShape.base()");
}
}
public class Main {
static <T extends Shape> void testShape(T shape){
shape.base();
}
...
}
向前迈出的一步是使 Shape
成为一个接口,而不是创建实现该接口的每个形状 class(TriangleShape
、OtherShape
、...)。
无论如何请注意,在您的示例中您并不真正需要泛型,如果您稍后需要引用相同的类型,它们会非常有用,例如 return 从方法中取回它:
static <T extends Shape> T testShape(T shape){
shape.base();
return shape;
}
在上面的示例中,您仍然可以将此类方法的结果分配给与传入参数相同的类型,因为参数类型和 return 类型相同 (T
)。
只有为 类.
实现相同的接口才能做到这一点
interface S {
void base();
}
static void testShape(S shape){
shape.base();
}
您收到的实际错误消息是:
The method base() is undefined for the type T
这正是您的问题:您的方法旨在对类型 T
进行操作,并且您说过 T
可以是 字面意思上的任何对象类型.由于 T
可能是 String
,或 Number
,或其他人创建的其他随机对象,您不能假设它在该对象上有任何特定方法。因此,方法 base()
对于类型 T
是 undefined,因为 T
不一定是具有 base()
方法的类型.这有意义吗?
如果您想要对 任何具有 base()
方法 的类型进行操作,那就是一个叫做 structural typing which Java unfortunately does not support. (Java's type system is nominative 的东西。)
下一个最好的事情是定义一个接口来保存你的 base()
方法,并在你的 类:
中实现该接口
interface ShapeInterface {
void base();
}
class Shape implements ShapeInterface {
...
}
class OtherShape implements ShapeInterface {
...
}
但是你不再需要参数多态性(即泛型),因为你可以使用普通的旧subtype polymorphism 相反:由于 Shape
和 OtherShape
都支持 is-a 与 ShapeInterface
的关系,您的 testShape
方法只能接受一个ShapeInterface
并直接与之互动:
static void testShape(ShapeInterface shape) {
shape.base();
}
我正在尝试理解 java 中的泛型,并尝试这个简单的示例,但无法使其工作;它返回错误
Exception in thread "main" java.lang.Error: Unresolved compilation problem: The method base() is undefined for the type T at javaTest.Main.testShape(Main.java:21) at javaTest.Main.main(Main.java:25)
下面是代码
class Shape{
int id=1;
void base(){
System.out.println("Shape.base()");
}
}
// unrelated class, but same func name
class OtherShape{
float id=1.1f;
void base(){
System.out.println("OtherShape.base()");
}
}
public class Main {
static <T>void testShape(T shape){
shape.base();
}
public static void main(String[] args) {
testShape(new Shape() );
testShape(new OtherShape());
}
}
关于如何让它发挥作用的任何想法?
我相信您遇到了这个问题,因为您没有将 T 转换为任何对象类型。尝试这样做。
class Shape{
int id=1;
void base(){
System.out.println("Shape.base()");
}
}
// unrelated class, but same func name
class OtherShape extends Shape{
float id=1.1f;
void base(){
System.out.println("OtherShape.base()");
}
}
public class Test {
static void testShape(Shape shape){
shape.base();
}
public static void main(String[] args) {
testShape(new Shape() );
testShape(new OtherShape());
}
}
在 Java 中,泛型是在没有外部上下文的情况下编译的,因此代码必须有效,而不知道最终将如何调用它。
声明某些东西 <T>
意味着您可以传递任何对象,因此 T var
意味着在编译时 var
应该只是 java.lang.Object
。因此 var.base()
没有意义,因为 java.lang.Object
没有提供名为 base()
.
你可以告诉 T
至少是 Shape
例如通过声明 <T extends Shape>
,然后你可以传递从 Shape
继承的任何东西。但是,您的第二个示例仍然无效,因为 OtherShape
没有继承自 Shape
,即它不满足条件 <T extends Shape>
.
要完全修复它,它应该如下所示:
class Shape{
int id=1;
void base(){
System.out.println("Shape.base()");
}
}
// unrelated class, but same func name
class OtherShape extends Shape{
float id=1.1f;
@Override
void base(){
System.out.println("OtherShape.base()");
}
}
public class Main {
static <T extends Shape> void testShape(T shape){
shape.base();
}
...
}
向前迈出的一步是使 Shape
成为一个接口,而不是创建实现该接口的每个形状 class(TriangleShape
、OtherShape
、...)。
无论如何请注意,在您的示例中您并不真正需要泛型,如果您稍后需要引用相同的类型,它们会非常有用,例如 return 从方法中取回它:
static <T extends Shape> T testShape(T shape){
shape.base();
return shape;
}
在上面的示例中,您仍然可以将此类方法的结果分配给与传入参数相同的类型,因为参数类型和 return 类型相同 (T
)。
只有为 类.
实现相同的接口才能做到这一点interface S {
void base();
}
static void testShape(S shape){
shape.base();
}
您收到的实际错误消息是:
The method base() is undefined for the type T
这正是您的问题:您的方法旨在对类型 T
进行操作,并且您说过 T
可以是 字面意思上的任何对象类型.由于 T
可能是 String
,或 Number
,或其他人创建的其他随机对象,您不能假设它在该对象上有任何特定方法。因此,方法 base()
对于类型 T
是 undefined,因为 T
不一定是具有 base()
方法的类型.这有意义吗?
如果您想要对 任何具有 base()
方法 的类型进行操作,那就是一个叫做 structural typing which Java unfortunately does not support. (Java's type system is nominative 的东西。)
下一个最好的事情是定义一个接口来保存你的 base()
方法,并在你的 类:
interface ShapeInterface {
void base();
}
class Shape implements ShapeInterface {
...
}
class OtherShape implements ShapeInterface {
...
}
但是你不再需要参数多态性(即泛型),因为你可以使用普通的旧subtype polymorphism 相反:由于 Shape
和 OtherShape
都支持 is-a 与 ShapeInterface
的关系,您的 testShape
方法只能接受一个ShapeInterface
并直接与之互动:
static void testShape(ShapeInterface shape) {
shape.base();
}