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

发布于 2024-09-18 20:22:14 字数 685 浏览 4 评论 0原文

我想调用一个可能采用不同版本的方法,即对于类型为

  • boolean
  • byte
  • Short
  • int
  • long 的

输入参数使用相同的方法 我想要执行此操作的方法是“重载”该方法(我认为这是正确的术语?):

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

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

有没有一种方法可以在不创建新类或使用原始类型的对象版本的情况下执行此操作?如果没有,有什么替代策略的建议吗?

让我知道我是否应该进一步解释以消除任何混乱。


更新

我实际上想做的是从一组位构造原始类型。因此,如果我正在处理该方法的字节版本,我几乎希望完成工作来获取 8 位并返回该字节(因为我无法通过引用传递)。

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

I would like to call a method which could potentially take on different versions, i.e. the same method for input parameters that are of type:

  • boolean
  • byte
  • short
  • int
  • long

The way I would like to do this is by "overloading" the method (I think that is the correct term?):

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

... but that would mean that I would have to pass the primitive type in by reference... similar to C++ where the method has external effect, where it can modify the variable outside its scope.

Is there a way to do this without creating new classes or using the Object versions of the primitive types? If not, any suggestions on alternative strategies?

Let me know if I should further explain to clear up any confusion.


UPDATE

What I'm actually trying to do is construct the primitive type from a set of bits. So if I'm dealing with the byte version of the method, I want to pretty much do my work to get 8 bits and return the byte (since I can't pass by reference).

The reason I'm asking this question is because the work I do with bits is very repetitive and I don't want to have the same code in different methods. So I want to find a way for my ONE method to KNOW how many bits I'm talking about... if I'm working with a byte, then 8 bits, if I'm working with a short, 16 bits, etc...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

自演自醉 2024-09-25 20:22:14

Java 始终按值传递。 Java 中没有引用传递。 它已写在规范中

Java is always pass-by-value. There is no pass-by-reference in Java. It's written in the specs!

陈甜 2024-09-25 20:22:14

虽然Java 支持重载,但所有参数均按值传递,即分配方法参数对调用者不可见。

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

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

如果这实际上是一个转换,那么标准命名是

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

While Java supports overloading, all parameters are passed by value, i.e. assigning a method argument is not visible to the caller.

From your code snippet, you are trying to return a value of different types. Since return types are not part of a method's signature, you can not overload with different return types. Therefore, the usual approach is:

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

If this is actually a conversion, the standard naming is

int toInt() { ...}
byte toByte() { ... }
自控 2024-09-25 20:22:14

你不能。在 Java 中,参数总是按值传递。如果参数是引用类型,则引用按值传递,您可以在方法内修改它,而对于原始类型,这是不可能的。

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

You can't. In Java parameters are always passed by value. If the parameter is a reference type, the reference is passed by value and you can modify it inside the method while with primitive types this is not possible.

You will need to create a wrapper type.

南烟 2024-09-25 20:22:14

基元不是通过引用(或就此而言的对象)传递的,所以不可以。

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

打印出1

Primitives are not passed by references (or objects for that matter) so no you cannot.

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

Prints out 1

最笨的告白 2024-09-25 20:22:14

我想说,如果您想使用原语,另一种策略是执行 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);

但我不明白它对于您的图书馆的客户来说有什么不那么麻烦的地方。

I would say the alternative strategy, if you want to work with primitives, is to do what the Java Libraries do. Just suck it up and have multiple methods.

For example, ObjectInputStream has readDouble(), readByte(), etc.

You're not gaining anything by sharing an implementation of the function, and the clients of your function aren't gaining anything by the variants of your function all having the same name.

UPDATE

Considering your update, I don't think it's necessary to duplicate too much code. It depends on your encoding strategy but I would imagine you could do something like this:

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

Anything that shares code more than that is probably over-engineering.

An alternative could be

private long getBits(int numBits);

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

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

i.e. I don't think it makes sense to expose the users of your library to anything other than the primitive types themselves.

If you really, really wanted to then you could make a single method for access like this:

@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);

But I fail to see how it's any less cumbersome for clients of your library.

﹏半生如梦愿梦如真 2024-09-25 20:22:14

如果我没记错的话,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);

希望有帮助。

The object types of primitive types in Java (Double, Integer, Boolean, etc) are, if I remember correctly, immutable. This means that you cannot change the original value inside a method they are passed into.

There are two solutions to this. One is to make a wrapper type that holds the value. If all you are attempting to do is change the value or get a calculation from the value, you could have the method return the result for you. To take your examples:

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

And you would call them by the following:

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

or something similar. This allows you to mutate or change the value, and return the mutated value, which would allow something like the following:

Short s = foo.getValue(10);

Hope that helps.

芯好空 2024-09-25 20:22:14

是的,请更具体地说明您想要实现的目标。
根据您的描述,我建议您看一下 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());

  }

}

Yes, please be more specific about what you want to achieve.
From your description I suggest you have a look at Java generics where you could write something like this:

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());

  }

}
一场春暖 2024-09-25 20:22:14

听起来你有一组正在解析的位。您应该将其包装在一个对象中,让我们将该对象称为 BitSet。您正在迭代这些位,因此您将拥有类似 Iterator的东西,并且当您进行操作时,您想要解析出字节、整数、长整型等...对吗?

然后你将拥有你的类 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
}

等等...

所以在调用你需要的任何方法之后,你已经以类型安全的方式提取了你想要的值(不同的方法有不同的返回类型) ,并且迭代器已根据类型向前移动了正确的位置数。

这就是您要找的吗?

Sounds like you have a set of bits that you're parsing through. You should have it wrapped in an object, lets call that object a BitSet. You're iterating through the bits, so you'll have something like an Iterator<Bit>, and as you go you want to parse out bytes, ints, longs, etc... Right?

Then you'll have your class Parser, and it has methods on it like:

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
}

etc...

So after you call whichever method you need, you've extracted the value you want in a typesafe way (different return types for different methods), and the Iterator has been moved forward the correct number of positions, based on the type.

Is that what you're looking for?

别理我 2024-09-25 20:22:14

只有创建自己的价值持有类型。

Only by creating your own value holding types.

往日 2024-09-25 20:22:14

如果我们真的想做类似的事情,我们可以使用一个技巧:)

public static void main(String[] args) {
    int[] count = {0};
    System.out.println(countZero(10304450, count)[0]);
    System.out.println();
}

private static int[] countZero(int n, int[] count) {

    if (n == 0)
        return count;

    int mod = n % 10;
    if(mod == 0)
        count[0] = count[0] + 1;

    return countZero(n/10,count);

}

这是一个计算数字中零个数的程序。

这里我们需要改变作为参数传递给函数的计数变量,当我们得到 0 时。

但是如果我们传递普通/原始整数,它就不起作用,我们知道为什么:)

但是如果我们使用一个技巧,即数组对于大小为 1 的整数,我们可以执行如上所示的操作。!

If we really want to do something like that we can use a trick :)

public static void main(String[] args) {
    int[] count = {0};
    System.out.println(countZero(10304450, count)[0]);
    System.out.println();
}

private static int[] countZero(int n, int[] count) {

    if (n == 0)
        return count;

    int mod = n % 10;
    if(mod == 0)
        count[0] = count[0] + 1;

    return countZero(n/10,count);

}

This is a program to count number of zero in a Digit.

Here we need to mutate the count variable that is passed to the Function as parameter, when ever wee will get 0.

But if we pass normal/ Primitive integer, it wont work , we know why :)

But if we use a trick i.e array of Integer of size 1 we can do something like as shown above.!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文