thk*_*ala 37 java primitive code-duplication
在我的一个Java项目中,由于Java处理(而非)原语的方式,我受到代码重复的困扰.具有相同的变化手工复制到四个不同的位置(之后int,long,float,double)再次,对于第三次的时候,再和再次我来到非常接近(?)来抢购.
在各种形式中,这个问题已经在StackOverflow上提出了:
共识似乎趋向于两种可能的替代方案:
好吧,第二个解决方案就是我现在正在做的事情,它对我的理智慢慢变得危险,就像众所周知的折磨技术一样.
自从提出这些问题并且Java 7出现以来已过去两年了.因此,我希望有一个更简单和/或更标准的解决方案.
Java 7是否有任何可能在这种情况下缓解压力的变化?我在简明的变更摘要中找不到任何内容,但也许在某处有一些不起眼的新功能?
虽然源代码生成是另一种选择,但我更喜欢使用标准JDK功能集支持的解决方案.当然,使用cpp或其他代码生成器可以工作,但它添加了更多的依赖项,并需要更改构建系统.
似乎JDK支持的唯一代码生成系统是通过注释机制.我设想一个可以像这样扩展源代码的处理器:
@Primitives({ "int", "long", "float", "double" })
@PrimitiveVariable
int max(@PrimitiveVariable int a, @PrimitiveVariable int b) {
return (a > b)?a:b;
}
Run Code Online (Sandbox Code Playgroud)
理想的输出文件将包含此方法的四个请求变体,最好使用相关的Javadoc注释等.是否有某处注释处理器来处理这种情况?如果没有,构建一个会怎样?
也许最近出现了一些其他技巧?
编辑:
一个重要的注意事项:除非我有理由,否则我不会使用原始类型.即使是现在,在某些应用程序中使用盒装类型也会产生非常真实的性能和内存影响.
编辑2:
使用max()作为示例允许使用compareTo()所有数字盒装类型中可用的方法.这有点棘手:
int sum(int a, int b) {
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
怎么可以为所有数字盒装类型支持这种方法而不实际写入六到七次?
Pet*_*rey 18
我倾向于使用"超类型" long或者double如果我仍然想要一个基元.性能通常非常接近,避免产生大量变化.BTW:无论如何,64位JVM中的寄存器都是64位的.
Boh*_*ian 15
你为什么要挂在原始人身上?包装器非常轻巧,自动装箱,其余的是泛型:
public static <T extends Number & Comparable<T>> T max(T a, T b) {
return a.compareTo(b) > 0 ? a : b;
}
Run Code Online (Sandbox Code Playgroud)
这一切都编译并正确运行:
public static void main(String[] args) {
int i = max(1, 3);
long l = max(6,7);
float f = max(5f, 4f);
double d = max(2d, 4d);
byte b = max((byte)1, (byte)2);
short s = max((short)1, (short)2);
}
Run Code Online (Sandbox Code Playgroud)
OP已经询问了一个通用的,自动装箱的解决方案sum(),并且将在这里.
public static <T extends Number> T sum(T... numbers) throws Exception {
double total = 0;
for (Number number : numbers) {
total += number.doubleValue();
}
if (numbers[0] instanceof Float || numbers[0] instanceof Double) {
return (T) numbers[0].getClass().getConstructor(String.class).newInstance(total + "");
}
return (T) numbers[0].getClass().getConstructor(String.class).newInstance((total + "").split("\\.")[0]);
}
Run Code Online (Sandbox Code Playgroud)
它有点蹩脚,但并不像执行大量系列instanceof并委托给完全类型的方法那样蹩脚.这instanceof是必需的,因为虽然所有Numbers都有一个String构造函数,Numbers除了Float并且Double只能解析一个整数(没有小数点); 虽然总数将是一个整数,但我们必须从Double.toString()将它们发送到这些其他类型的构造函数之前删除小数点.
Java 7是否有任何可能在这种情况下缓解压力的变化?
没有.
有没有一个注释处理器来处理这种情况?
不是我知道的.
如果没有,构建一个会怎样?
时间还是金钱.:-)
在我看来,这似乎是一个问题空间,很难找到一个运行良好的通用解决方案......超越琐碎的案例.传统的源代码生成或(文本)预处理器似乎对我更有希望.(虽然我不是Annotation处理器专家.)