Java访问者模式同时使用基元类型和类

Java访问者模式同时使用基元类型和类,java,Java,我正在努力减少一个项目所需的方法数量,因此,我希望找到一种根据输入参数的类型/类别动态执行操作的方法,而不是过多的重载。 我有基本类型(long、double)和类(String、array或自定义类)的参数 我有一个应该对所有人都可用的方法,这个方法也是重载的 public void write(long n){ //Some operations } public void write(String str){ //Some other operations } 我尝试使

我正在努力减少一个项目所需的方法数量,因此,我希望找到一种根据输入参数的类型/类别动态执行操作的方法,而不是过多的重载。 我有基本类型(long、double)和类(String、array或自定义类)的参数

我有一个应该对所有人都可用的方法,这个方法也是重载的

public void write(long n){
    //Some operations
}

public void write(String str){
    //Some other operations
}
我尝试使用Java泛型类型,但没有成功——就像这样

public <T> void mainMethod(T... inputs){
    for (T input: inputs){
        write(input);
    }    
}
public void main方法(T…输入){
用于(T输入:输入){
写入(输入);
}    
}
这将导致无法解析方法“write(T)”时出错。 我想我可以处理一些instanceof和其他铸造操作,但我只是想知道是否还有其他方法


提前谢谢

假设所有对象和类型都有不同的
write
,需要不同的处理,我可以想出五种方法

错误:将main方法更改为包含大量检查的
实例。这不会降低
write()
的重载方法计数。一些IDE会发出警告,说这还不够“面向对象”

错误:使
write()
接受
Object
并将
的链放置在那里。相同的IDE警告

否:您可以将
write
的功能从实用程序类中取出,并将其放入每个对象的子类中,否则将传递给
write
。这是不可能的,因为原语。你们可以延长电话号码,但这很麻烦

否:您可以根据参数类型为每个对象
T input
反射性地获取正确的方法并调用该方法。仍然无法回答您关于如何减少重载数量的问题

最好的方法:试着找出你想要用这些完全不同的参数做什么的共同点。在
write
的情况下,可能是转换为
String
或某种形式的序列化或转换。在这些情况下,你可以做两件事

  • “预处理”对象(例如
    String.valueOf()
    .toString()
    或您自己的方法)以获得一个或少量类型,因此您不需要那么多方法。(就像用
    系统.out.println所做的那样
  • 为所有非基本类创建一个接口,表示
    write
    函数可以接受这些类(就像
    Serializable
    所做的那样)。此接口应该公开
    write
    可以使用的一些方法,以消除对
    if
    链的需要

至于为什么
实例链是坏的,我引用IntelliJ的警告:

报告所有条件为 表达式实例或类相等表达式(例如比较 使用String.class)。这种结构通常表明结构失效 面向对象的设计,它规定这种基于类型的分派 应该通过多态方法调用而不是显式调用来完成 型式试验链


如果您试图声明
Long
而不是
Long
,编译器应注意自动取消装箱这取决于方法的功能。例如,如果您的
write
方法只是将对象转换为字符串并将其写入文件或其他内容,您只需选择
public void write(object obj)
作为方法签名并调用
obj.toString()
因为实际调用的方法不依赖于声明的类型而不是运行时类型。您是指从mainMethod还是从write函数?后面的一个实际上来自另一个库,所以我认为我不应该改变它的方式。当
t
在运行时只能表示一种类型时,为什么需要一堆实例减少方法计数是一个不好的目标。好的代码几乎总是由许多小方法组成。即使减少方法数量是有用的,但仅仅添加动态调度(这正是您要问的)也无法实现这一点。Otoh,通过重构减少重复代码是一个很好的目标。消除基于对象类型的分支是一个很好的目标。你真的想达到最后两个目标之一吗?还有什么吗?谢谢,但我还是想知道为什么让write()接受对象不好。。?我可以保留write(对象o)和其他自定义类的write方法吗?我假设所有对象都需要不同的处理(答案更新)。在接受
对象的单个方法中
需要一个
实例链
,这是不好的做法。另一方面,如果您只需要将
String.valueOf()和
Arrays.toString()
用于数组中的任何对象,则不需要自定义类的方法。