如何将10乘以一个“1”;整数;Java中的对象?

如何将10乘以一个“1”;整数;Java中的对象?,java,types,casting,Java,Types,Casting,如何将10乘以一个整数对象,然后返回整数对象 我正在寻找最整洁的方法 我可能会这样做: 从Integer对象中获取int,将其与其他int相乘,并使用此int值创建另一个Integer对象 代码将类似于 integerObj = new Integer(integerObj.intValue() * 10); 但是,我看到一段代码,作者是这样做的:从Integer对象获取String,在末尾连接“0”,然后使用Integer.parseInt返回Integer对象 代码如下所示: String

如何将10乘以一个
整数
对象,然后返回
整数
对象

我正在寻找最整洁的方法

我可能会这样做: 从
Integer
对象中获取int,将其与其他int相乘,并使用此int值创建另一个Integer对象

代码将类似于

integerObj = new Integer(integerObj.intValue() * 10);
但是,我看到一段代码,作者是这样做的:从
Integer
对象获取
String
,在末尾连接“0”,然后使用
Integer.parseInt
返回
Integer
对象

代码如下所示:

String s = integerObj + "0";
integerObj = Integer.parseInt(s);
这样做有什么好处吗


一般来说,在这种情况下,最有效/最整洁的方法是什么?

字符串方法很有趣,但几乎肯定是一种不好的方法

获取整数的int值并创建一个新值将非常快,而调用as parseInt将非常昂贵

总的来说,我同意您最初的方法(正如其他人所指出的,如果您使用Java 5中引入的自动装箱,则可以在没有太多混乱的情况下完成此方法)。

使用Java 5,您只需执行以下操作:

Integer a = new Integer(2); // or even just Integer a = 2;
a *= 10;
System.out.println(a);

远离第二种方法,最好的选择是自动装箱如果您使用的是java 1.5,那么第一个示例之前的任何方法都是最好的。

由于各种原因,使用String方法的解决方案不太好。有些是美学上的原因,有些是实用的

实际上,字符串版本创建的对象比普通形式创建的对象多(如第一个示例所示)


从美学角度讲,我认为第二个版本模糊了代码的意图,这几乎与让它产生您想要的结果一样重要。

第二种方法的问题是Java处理字符串的方式:

  • “0”
    在编译时转换为常量字符串对象
  • 每次调用此代码时,
    s
    被构造为一个新的字符串对象,并且
    javac
    将该代码转换为
    String s=new StringBuilder().append(integerObj.toString()).append(“0”).toString()
    (旧版本的StringBuffer)。即使您使用相同的
    integerObj
    ,即

    String s1=integerObj+“0”;
    字符串s2=整数BJ+“0”

    (s1==s2)
    将为
    false
    ,而
    s1.equals(s2)
    将为
    true

  • Integer.parseInt
    内部调用
    newinteger()
    ,因为
    Integer
    是不可变的


顺便说一句,自动装箱/取消装箱在内部与第一种方法相同。

toolkit上面的答案是正确的,也是最好的方法,但它没有对发生的情况给出完整的解释。 假设Java 5或更高版本:

Integer a = new Integer(2); // or even just Integer a = 2;
a *= 10;
System.out.println(a); // will output 20
您需要知道的是,这与执行以下操作完全相同:

Integer a = new Integer(2); // or even just Integer a = 2;
a = a.intValue() * 10;
System.out.println(a.intValue()); // will output 20
通过对对象“a”执行操作(在本例中为*=),您不会更改“a”对象内的int值,而是实际将新对象分配给“a”。 这是因为“a”会自动取消装箱以执行乘法,然后乘法的结果会自动装箱并分配给“a”

整数是一个不可变的对象。(所有包装器类都是不可变的。)

以这段代码为例:

static void test() {
    Integer i = new Integer(10);
    System.out.println("StartingMemory: " + System.identityHashCode(i));
    changeInteger(i);
    System.out.println("Step1: " + i);
    changeInteger(++i);
    System.out.println("Step2: " + i.intValue());
    System.out.println("MiddleMemory: " + System.identityHashCode(i));
}

static void changeInteger(Integer i) {
    System.out.println("ChangeStartMemory: " + System.identityHashCode(i));
    System.out.println("ChangeStartValue: " + i);
    i++;
    System.out.println("ChangeEnd: " + i);
    System.out.println("ChangeEndMemory: " + System.identityHashCode(i));
}
输出将是:

StartingMemory: 1373539035
ChangeStartMemory: 1373539035
ChangeStartValue: 10
ChangeEnd: 11
ChangeEndMemory: 190331520
Step1: 10
ChangeStartMemory: 190331520
ChangeStartValue: 11
ChangeEnd: 12
ChangeEndMemory: 1298706257
Step2: 11
MiddleMemory: 190331520
MiddleMemory: 190331520
Step2: 15
MiddleMemory: 190331520
您可以看到“i”的内存地址正在更改(您的内存地址将不同)

现在让我们用反射进行一个小测试,将其添加到test()方法的末尾:

额外的产出将是:

StartingMemory: 1373539035
ChangeStartMemory: 1373539035
ChangeStartValue: 10
ChangeEnd: 11
ChangeEndMemory: 190331520
Step1: 10
ChangeStartMemory: 190331520
ChangeStartValue: 11
ChangeEnd: 12
ChangeEndMemory: 1298706257
Step2: 11
MiddleMemory: 190331520
MiddleMemory: 190331520
Step2: 15
MiddleMemory: 190331520
您可以看到,“i”的内存地址没有更改,即使我们使用反射更改了它的值。

(现实生活中不要以这种方式使用反射!!)

不建议使用整数构造函数。使用自动装箱或valueOf()代替…
Integer。parseInt(…)
不必创建Integer对象,它直接与原语
int
一起工作。我还建议您检查是否确实需要使用Integer。Joshua指出,在高效的Java中使用原语的速度要快很多倍。所以,如果可以,请坚持使用int。使用Integer实际上是一个设计约束。我的想法是得到一个整数对象,我必须更新它。因此,无法消除:)如果没有反射巫毒,更新现有的整数对象是不会发生的。(Integer和其他基本包装类型一样,是不可变的。)您可以合理地做的最好的事情——任何正常的示例都会做的事情——就是用另一个对象替换它。这对于大多数情况来说已经足够了,但意味着
void modifyInteger(Integer i)
不会做任何有价值的事情。