我可以通过Java中的引用传递原始类型吗?

时间:2010-09-07 20:09:12

标签: java pass-by-reference overloading primitive-types

我想调用一个可能采用不同版本的方法,即类型为输入参数的方法相同:

  • 布尔
  • 字节
  • INT

我想这样做的方法是“重载”方法(我认为这是正确的术语?):

public void getValue(byte theByte) {...}
public void getValue(short theShort) {...}
... etc ...

...但这意味着我必须通过引用传递原始类型...类似于C ++,其中方法具有外部效果,它可以修改其范围之外的变量。

有没有办法在不创建新类或使用原始类型的Object版本的情况下执行此操作?如果没有,有关替代战略的任何建议吗?

让我知道是否应该进一步解释清除任何混淆。


更新

我实际上要做的是从一组位构造基本类型。因此,如果我正在处理方法的字节版本,我希望我的工作能够得到8位并返回字节(因为我无法通过引用传递)。

我问这个问题的原因是因为我对比特的工作是非常重复的,我不想在不同的方法中使用相同的代码。所以我想找到一种方法让我的ONE方法知道我正在谈论多少位......如果我正在使用一个字节,那么就是8位,如果我正在处理一个短的16位等等...

9 个答案:

答案 0 :(得分:9)

Java is always pass-by-value。 Java中没有pass-by-reference。 It's written in the specs

答案 1 :(得分:8)

当Java支持重载时,所有参数都按值传递,即调用者看不到分配方法参数。

在您的代码段中,您尝试返回不同类型的值。由于返回类型不是方法签名的一部分,因此不能使用不同的返回类型进行重载。因此,通常的做法是:

int getIntValue() { ... }
byte getByteValue() { ... }

如果这实际上是转换,则标准命名为

int toInt() { ...}
byte toByte() { ... }

答案 2 :(得分:5)

你做不到。在Java中,参数始终按值传递。如果参数是引用类型,则引用按值传递,您可以在方法内修改它,而使用基本类型则不可能。

您需要创建一个包装类型。

答案 3 :(得分:1)

基元不会通过引用(或对象)传递,所以不能不能。

int i = 1;
moo(i);
public void moo(int bah)
{
   bah = 3;
}
System.out.println(i);

打印1

答案 4 :(得分:1)

如果我没记错的话,Java中的基本类型的对象类型(Double,Integer,Boolean等)是不可变的。这意味着您无法在传入的方法中更改原始值。

这有两个解决方案。一种是制作一个包含值的包装器类型。如果你要做的就是更改值或从值中获得计算,你可以让方法为你返回结果。举个例子:

public byte getValue(byte theByte) {...}
public short getValue(short theShort) {...}

你可以通过以下方式给他们打电话:

Short s = 0;
s = foo.getValue(s);

或类似的东西。这允许您改变或更改值,并返回变异值,这将允许以下内容:

Short s = foo.getValue(10);

希望有所帮助。

答案 5 :(得分:1)

我想说,如果你想使用原语,替代策略就是做Java库的工作。只是搞砸了,有多种方法。

例如,ObjectInputStream包含readDouble()readByte()等。

你没有通过共享函数的实现来获得任何东西,并且函数的客户端没有通过函数的变体获得任何东西都具有相同的名称。

<强>更新

考虑到您的更新,我认为没有必要复制太多代码。这取决于你的编码策略,但我想你可以做这样的事情:

private byte get8Bits();
public byte getByte() {
    return get8Bits();
}
public int getInt() {
    return (get8Bits() << 24) | (get8Bits() << 16) | (get8Bits() << 8) | get8Bits();
}

任何共享代码的东西都可能过度工程化。

另一种选择可能是

private long getBits(int numBits);

public byte getByte() {
    return (byte)getBits(8);
}

public int getInt() {
    return (int)getBits(32);
}

即。我认为将库的用户暴露给原始类型本身以外的任何东西都没有意义。

如果你真的那么想,那么你就可以制作一个单一的访问方法:

@SuppressWarnings("unchecked")
public static <T> T getValue(Class<T> clazz) {
    if ( clazz == byte.class ) {
        return (T)Byte.valueOf((byte)getBits(8));
    } else if ( clazz == int.class ) {
        return (T)Integer.valueOf((int)getBits(32));
    }
    throw new UnsupportedOperationException(clazz.toString());
}

//...
byte b = getValue(byte.class);
int i = getValue(int.class);

但我没有看到你的图书馆客户如何笨重。

答案 6 :(得分:1)

听起来你有一组你正在解析的位。你应该将它包装在一个对象中,让我们将该对象称为BitSet。你正在迭代这些位,所以你会有像Iterator&lt; Bit&gt;这样的东西,当你想要解析字节,整数,长整数等时......对吗?

然后你将拥有你的Parser类,它的方法就像:

public byte readByte(Iterator<Bit> bitit) {
  //reads 8 bits, which moves the iterator forward 8 places, creates the byte, and returns it
}
public int readInt(Iterator<Bit> bitit) {
  //reads 32 bits, which moves the iterator forward 32 places, creates the int, and returns it
}

等...

因此,在调用所需的任何方法后,您已经以类型安全的方式提取了所需的值(不同方法的不同返回类型),并且Iterator已根据类型向前移动了正确的位置数

这就是你要找的东西吗?

答案 7 :(得分:0)

只能创建自己的值保持类型。

答案 8 :(得分:0)

是的,请更具体地说明您想要实现的目标。 根据您的描述,我建议您查看Java泛型,您可以在其中编写如下内容:

class SomeClass <GenericType> {
  GenericType val;  

  void setValue(GenericType val) {
     this.val = val;
  }

  GenericType getValue() {
     return val;
  }

  public static void main(String[] args) {
    SomeClass<Integer> myObj = new SomeClass<Integer>();
    myObj.setValue(5);
    System.out.println(myObj.getValue());

    SomeClass<String> myObj2 = new SomeClass<String>();
    myObj2.setValue("hello?!");
    System.out.println(myObj2.getValue());

  }

}