Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java泛型函数中访问具体属性_Java_Generics - Fatal编程技术网

在Java泛型函数中访问具体属性

在Java泛型函数中访问具体属性,java,generics,Java,Generics,我不熟悉Java泛型。我编写了一个函数,如下所示: public class C<T extends MyClass> implements MyInterface<T>{ public void f(T obj){ ... obj.getName() } } 上面的函数f是为两种类型的对象MySubClass1和MySubClass2调用的。MySubClass1和MySubClass2是从抽象类M

我不熟悉Java泛型。我编写了一个函数,如下所示:

  public class C<T extends MyClass> implements MyInterface<T>{
      public void f(T obj){
         ...
         obj.getName()
      }
   }
上面的函数f是为两种类型的对象MySubClass1和MySubClass2调用的。MySubClass1和MySubClass2是从抽象类MyClass继承的两个具体类,name是MySubClass2的一个属性

当用MySubClass2的对象调用f时,我希望访问上面的名称。我不知道该怎么做

…名称是MySubClass2的一个属性

那么您的方法就不能依赖它的存在,因为obj可以是从MyClass派生的任何东西

这意味着您的设计应该改变,要么使用单独的方法,要么将名称移动到MyClass

您可以使用instanceof check和cast来执行此操作:

if (obj instanceof MySubClass2) {
    String name = ((MySubClass2)obj).getName();
}
…但是十有八九,使用instanceof应该会让你后退一步,重新考虑你的设计

…名称是MySubClass2的一个属性

那么您的方法就不能依赖它的存在,因为obj可以是从MyClass派生的任何东西

这意味着您的设计应该改变,要么使用单独的方法,要么将名称移动到MyClass

您可以使用instanceof check和cast来执行此操作:

if (obj instanceof MySubClass2) {
    String name = ((MySubClass2)obj).getName();
}

…但十有八九,使用instanceof应该会让您后退一步,重新考虑您的设计。

在将T约束到MyClass的通用方法中,只有MyClass的方法可用。由于getName只在MySubClass2中实现,因此在没有对MySubClass2进行强制转换的情况下无法访问getName,这与将f方法设置为泛型的目的背道而驰

您可以传递一个函数对象,将名称从T拉到f,如下所示:

public void f(T obj, Function<T,String> getName){
    ...
    String name = getName.apply(obj);
}
MySubClass2 s2 = new MySubClass2();
MyInterface<MySubClass2> c = new C<>();
c.f(s2, MySubClass2::getName);
请注意,此技术允许您在MySubClass1对象上调用f,只要您提供某种获取名称的方法:

MySubClass1 s1 = new MySubClass1();
MyInterface<MySubClass1> c = new C<>();
c.f(s1, x -> "<no-name>");

在将T约束为MyClass的泛型方法中,只有MyClass的方法可用。由于getName只在MySubClass2中实现,因此在没有对MySubClass2进行强制转换的情况下无法访问getName,这与将f方法设置为泛型的目的背道而驰

您可以传递一个函数对象,将名称从T拉到f,如下所示:

public void f(T obj, Function<T,String> getName){
    ...
    String name = getName.apply(obj);
}
MySubClass2 s2 = new MySubClass2();
MyInterface<MySubClass2> c = new C<>();
c.f(s2, MySubClass2::getName);
请注意,此技术允许您在MySubClass1对象上调用f,只要您提供某种获取名称的方法:

MySubClass1 s1 = new MySubClass1();
MyInterface<MySubClass1> c = new C<>();
c.f(s1, x -> "<no-name>");

代码中有语法错误,缺少分号。您可以将obj强制转换为MySubClass2,但这是一个糟糕的设计。A可能会有帮助。这看起来像是一张照片。想详细说明一下您实际想要实现的目标吗?请提供@Aominè为什么需要在这里使用MCVE?您的代码中有一个语法错误,缺少分号。您可以将obj强制转换为MySubClass2,但这是一个糟糕的设计。A可能会有帮助。这看起来像是一张照片。想详细说明你真正想要实现的目标吗?请提供@Aominè为什么需要MCVE?此解决方案只会将问题提升一个级别。如果调用方一开始只有一个MyClass引用,尽管它可能包含一个MySubClass2,那该怎么办?@Turing85这个问题被嵌入到区分泛型调用中MyClass子类的任务中。这种丑陋必须在某个地方出现;我更喜欢调用站点而不是方法本身;T.J.展示了另一种选择。这种解决方案只会将问题提升一个层次。如果调用方一开始只有一个MyClass引用,尽管它可能包含一个MySubClass2,那该怎么办?@Turing85这个问题被嵌入到区分泛型调用中MyClass子类的任务中。这种丑陋必须在某个地方出现;我更喜欢调用站点而不是方法本身;T.J.展示了另一种选择。