目标:我需要创建一个或多个函数来处理不同类型的List
参数,我将遍历函数中的列表。
尝试:
1-具有不同类型列表的多个功能
public static int update(List<MyClass> myClasses){};
public static int update(List<Project> rojects){};
public static int update(List<Time> times){};
但由于具有相同参数类型List
的多个函数,这被视为无法编译。
2-通用类型的列表,并使用(instanceof
)然而,我没有完全做到这一点,因为我不确定如何,并且尽管我读到,这似乎是一种不利的方式动作。
我的问题:实现此类要求的Java方式是什么?我需要一个干净的代码,我不在乎它是否复杂,我主要关心准确性和正确的编码。
PS:如果instanceof
是正确的方式,那么请您提供一个关于如何使用不同类型迭代列表的小例子。
提前致谢:)
编辑:不同的对象彼此没有关系,因为它们不会相互扩展,也不会扩展超类。每个函数的块都生成一个SQLite语句,每个类型都不同。
回应'严厉的回答:
所以我最终结合使用了你的建议,那就是实现一个函数为getClassType()
的基类,它返回一个类名的字符串,然后我会检查{的返回值{1}}功能。
update(List<T> list)
整理public static <T extends Item> int update(List<T> list){
...
// Loop through the list and call the update function
for (T item: list){
if (item.getClassType() == MyClass.CLASS_TYPE)
update((MyClass) item);
}
...
}
public interface Item {
/**
* @return Return the class type, which is the name of the class
*/
public String getClassType();
}
public class ClassProject implements Item{
public static final String CLASS_TYPE = "ClassProject";
@Override
public String getClassType() {
return CLASS_TYPE;
}
...
}
public class ClassTime implements Item{
public static final String CLASS_TYPE = "ClassTime";
@Override
public String getClassType() {
return CLASS_TYPE;
}
...
}
public class MyClass implements Item{
public static final String CLASS_TYPE = "MyClass";
@Override
public String getClassType() {
return CLASS_TYPE;
}
...
}
的原因是因为我不喜欢interface
并且不确定它的性能和成本,所以我试图制作一个我自己的。{1}}。现在这是一种可怕的做法吗?
答案 0 :(得分:4)
你能做这样的事吗:
public class Update<T>
{
public static int update(List<T> objects){};
}
OR
public static <T> int update(List<T> objects){};
以你的情况为准。
因此,如果你采用第二种方法并且由于运行时的类型擦除,你将继续进行instanceof检查:
public static <T> int update(List<T> objects){
for(T object : objects)
{
if(object.getClass().isInstance(Pair.class))
{
//do something
}else if(object.getClass().isInstance(Time.class))
{
}
}
return 0;
}
但这看起来不是一个好的设计,你可以通过使用工厂方法来改进:
static Handler getHandler(Class<?> handlerClass)
{
if(handlerClass.isInstance(Project.class))
{
//return ProjectHandler
}else if(handlerClass.isInstance(Time.class))
{
//return TimeHandler
}
//return errorHandler
}
interface Handler {
int handle();
}
public static <T> int update(List<T> objects){
for(T object : objects)
{
getHandler(object.getClass()).handle();
}
return 0;
}
现在一个更好的方法IMO将通过标记接口指定更新的类,然后干净地处理每个类中的更新:
interface Updateable {
int update();
}
public static <T extends Updateable> int update2(List<T> objects){
for(T object : objects)
{
object.update();
}
return 0;
}
答案 1 :(得分:1)
根据您对我的评论的回答,您有两种方法。第一种方法是尝试提出一个接口,该接口将传递给此方法的所有可能类型实现。如果你的界面被称为Foo,你可以将方法定义为:
public int update(List<Foo> list)
然后你的代码将基于Foo中可用的方法。
如果您不能这样做,那么每种可能的类型都需要单独的方法。由于Type Erasure,您无法在运行时执行instanceof。如果列表在编译的代码中被擦除,则基础类型将不可用于逻辑实例。
编辑:
为了澄清我对上述答案的一点混淆。在迭代列表时,您可以基于每个元素执行instanceof
,如下所示:
for(Object item:list){
if (item instanceof A){
//do A based logic
}
else if (item instanceof B){
//do B based logic
}
}
但是,您无法在运行时检查列表类型,如下所示:
if (list instanceof List<A>)
您最好的选择是尝试通过我的第一个解决方案中建议的界面来支持所支持的类型。执行instanceof方法将导致在添加更多支持的类型时不断需要修改的代码。
答案 2 :(得分:0)
扩大苛刻的答案,你不能这样做:
public class Update
{
public static <T> int update(List<T> objects, Class<T> clazz){};
}
然后,在您的实现中,根据传递的Class实例改变行为?