泛型方法是否可以从您传递给它的类型中调用方法
Is it possible for a generic method to call a method from the type you pass into it
我有一个方法需要在很多class中使用。此方法旨在创建给定对象类型的新对象列表。此方法需要从每个 class(同一类方法的不同实现)中调用另一个方法。
我不想将方法 copy/paste 放入每个 class 并每次都更改对象类型,而是想创建一个带有泛型方法的泛型 class 来调用必要的方法来自每个 class。这可能吗?
这是我正在尝试做的事情:
public class Conversion<E> {
public static <E> List<E> toList(String str) {
//The string needs to be split because it contains
//the information to create multiple objects
String[] listArray = str.split(".");
List<E> list = new ArrayList<E>();
for (String s : listArray) {
//E.fromString() creates an object of the type E
//It is a static method
list.add(E.fromString(s));
}
return list;
}
}
当我尝试这个时,Eclipse
给我一个错误,说 fromString(String)
对于类型 E
是未定义的。我想要的有可能吗?
您可以创建一个接口,该接口执行从 String 到类型 E 的对话,并在您的方法中传递对象类型。如下所示:
public static <E> List<E> toList(String str, YourType<E> yourObject) {
//The string needs to be split because it contains
//the information to create multiple objects
String[] listArray = str.split(".");
List<E> list = new ArrayList<E>();
for (String s : listArray) {
//E.fromString() creates an object of the type E
//It is a static method
list.add(yourObject.fromString(s));
}
return list;
}
}
interface YourType<E>{
E fromString(String s);
}
最简单的修改是使用strategy pattern。
定义一个接口如
interface Parser<T> {
T fromString(String s);
}
并将签名更改为
public static <E> List<E> toList(String str, Parser<E> parser) {
然后使用parser.fromString(s)
,而不是E.fromString
示例用法
interface User {}
class UserParser implements Parser<User> {
@Override
public User fromString(String s) {
return new User() {};
}
}
toList("a.b.c", new UserParser());
假设:
如果有一些语言特性可以使静态方法成为接口契约的一部分,也许你可以像这样摆脱困境
interface Parsable<T> {
static T fromString(String s); // will not compile
}
public static <E extends Parseable<E>> List<E> toList(String str)
但这在 Java 中永远不会发生。不过,如果有另一种允许它的强类型语言,也不会感到惊讶。
关于它是否应该包含在 TypeScript 中似乎有些 hot discussion。
可以这样做,但这非常不安全
public static class Conversion {
public static <E> List<E> toList(String str, Class<E> clazz)
throws Exception {
//The string needs to be split because it contains
//the information to create multiple objects
String[] listArray = str.split("\.");
List<E> list = new ArrayList<E>();
Method fromStringMethod = clazz.getMethod("fromString", String.class);
for (String s : listArray) {
//E.fromString() creates an object of the type E
//It is a static method
Object object = fromStringMethod.invoke(null, s);
list.add((E) object);
}
return list;
}
}
public static class FromString {
private String field;
public FromString() {
}
public FromString(String st) {
this.field = st;
}
static public FromString fromString(String st) {
return new FromString(st);
}
@Override
public String toString() {
return "FromString{" +
"field=" + field +
'}';
}
}
@Test
public void test() throws Exception {
System.out.println(Conversion.toList("one.two.three", FromString.class));
}
输出:
[FromString{field=one}, FromString{field=two}, FromString{field=three}]
我有一个方法需要在很多class中使用。此方法旨在创建给定对象类型的新对象列表。此方法需要从每个 class(同一类方法的不同实现)中调用另一个方法。
我不想将方法 copy/paste 放入每个 class 并每次都更改对象类型,而是想创建一个带有泛型方法的泛型 class 来调用必要的方法来自每个 class。这可能吗?
这是我正在尝试做的事情:
public class Conversion<E> {
public static <E> List<E> toList(String str) {
//The string needs to be split because it contains
//the information to create multiple objects
String[] listArray = str.split(".");
List<E> list = new ArrayList<E>();
for (String s : listArray) {
//E.fromString() creates an object of the type E
//It is a static method
list.add(E.fromString(s));
}
return list;
}
}
当我尝试这个时,Eclipse
给我一个错误,说 fromString(String)
对于类型 E
是未定义的。我想要的有可能吗?
您可以创建一个接口,该接口执行从 String 到类型 E 的对话,并在您的方法中传递对象类型。如下所示:
public static <E> List<E> toList(String str, YourType<E> yourObject) {
//The string needs to be split because it contains
//the information to create multiple objects
String[] listArray = str.split(".");
List<E> list = new ArrayList<E>();
for (String s : listArray) {
//E.fromString() creates an object of the type E
//It is a static method
list.add(yourObject.fromString(s));
}
return list;
}
}
interface YourType<E>{
E fromString(String s);
}
最简单的修改是使用strategy pattern。 定义一个接口如
interface Parser<T> {
T fromString(String s);
}
并将签名更改为
public static <E> List<E> toList(String str, Parser<E> parser) {
然后使用parser.fromString(s)
,而不是E.fromString
示例用法
interface User {}
class UserParser implements Parser<User> {
@Override
public User fromString(String s) {
return new User() {};
}
}
toList("a.b.c", new UserParser());
假设:
如果有一些语言特性可以使静态方法成为接口契约的一部分,也许你可以像这样摆脱困境
interface Parsable<T> {
static T fromString(String s); // will not compile
}
public static <E extends Parseable<E>> List<E> toList(String str)
但这在 Java 中永远不会发生。不过,如果有另一种允许它的强类型语言,也不会感到惊讶。
关于它是否应该包含在 TypeScript 中似乎有些 hot discussion。
可以这样做,但这非常不安全
public static class Conversion {
public static <E> List<E> toList(String str, Class<E> clazz)
throws Exception {
//The string needs to be split because it contains
//the information to create multiple objects
String[] listArray = str.split("\.");
List<E> list = new ArrayList<E>();
Method fromStringMethod = clazz.getMethod("fromString", String.class);
for (String s : listArray) {
//E.fromString() creates an object of the type E
//It is a static method
Object object = fromStringMethod.invoke(null, s);
list.add((E) object);
}
return list;
}
}
public static class FromString {
private String field;
public FromString() {
}
public FromString(String st) {
this.field = st;
}
static public FromString fromString(String st) {
return new FromString(st);
}
@Override
public String toString() {
return "FromString{" +
"field=" + field +
'}';
}
}
@Test
public void test() throws Exception {
System.out.println(Conversion.toList("one.two.three", FromString.class));
}
输出:
[FromString{field=one}, FromString{field=two}, FromString{field=three}]