Java:如何通过引用传递字节[]?

Java:如何通过引用传递字节[]?,java,pass-by-reference,Java,Pass By Reference,您可以在.NET中使用关键字“ref”来完成此操作。在Java中有什么方法可以做到这一点吗?Java对方法参数使用传递值 (int、boolean等)是Java中的特例。。而不是对象本身。在这种情况下,将原语(参数)的副本传递到函数中。这与传递值理论非常吻合 对于对象,发生的情况是通过值传递对对象的引用(复制引用而不是对象)。。。但两个引用都指向同一个对象。因此,如果在方法中修改对象参数,实际对象将被修改 这篇文章应该对你有所帮助。。 至于OP的问题,只需将对byte[]数组的引用传递给该

您可以在.NET中使用关键字“ref”来完成此操作。在Java中有什么方法可以做到这一点吗?

Java对方法参数使用传递值

  • (int、boolean等)是Java中的特例。。而不是对象本身。在这种情况下,将原语(参数)的副本传递到函数中。这与传递值理论非常吻合
  • 对于对象,发生的情况是通过值传递对对象的引用(复制引用而不是对象)。。。但两个引用都指向同一个对象。因此,如果在方法中修改对象参数,实际对象将被修改
这篇文章应该对你有所帮助。。

至于OP的问题,只需将对byte[]数组的引用传递给该方法。最终结果将类似于通过引用传递。如果修改字节数组,调用方将能够在方法执行后看到更改

更新以消除阻力:)=>表示输出

.NET土地
类计数器
{
私有整数m_计数=0;
公共重写字符串ToString()
{
返回String.Format(“计数器ID{0}:值{1}”,this.GetHashCode(),m_count);
}
公共空间增量()
{m_count++;}
}
类MakeAPass
{
public void PassByValueAndModify(int i)
{i=20;}
public void PassByRefAndModify(ref int i)
{i=20;}
public void PassByValueAndModify(计数器c)
{c.Increment();}
公共无效PassByRefAndModify(参考计数器c)
{c.Increment();}
公共无效密码REFANDREASSIGN(参考计数器c)
{
c=新计数器();
对于(int i=0;i 10
对象PassByRefAndModify(ref intVal);
Console.WriteLine(intVal);//=>20
计数器obCounter=新计数器();
obj.PassByValueAndModify(对象计数器);
Console.WriteLine(obCounter.ToString());//=>计数器ID58225482:值1
对象PassByRefAndModify(参考对象计数器);
Console.WriteLine(obCounter.ToString());//=>计数器ID58225482:值2
对象PassByRefAndReassign(参考对象计数器);
Console.WriteLine(obCounter.ToString());//=>计数器ID54267293:值5
}
爪哇岛 次要mods reqd:使用hashCode()和+在Counter.java中压缩字符串

class MakeAPass
{
   public void PassByValueAndModify(int i)
   {   i = 20;   }

   // can't be done.. Use Integer class which wraps primitive
   //public void PassByRefAndModify(ref int i)

   public void PassByValueAndModify(Counter c)
   {   c.Increment();   }

   // same as above. no ref keyword though
   //public void PassByRefAndModify(ref Counter c)

   // this can't be done as in .net
   //public void PassByRefAndReassign(ref Counter c)
   public void PassAndReassign(Counter c)
   {
      c = new Counter();
      for (int i=0; i<5; ++i)
         c.Increment();
   }
}
public static void main(String args[])
{
   MakeAPass obj = new MakeAPass();
   int intVal = 10;
   obj.PassByValueAndModify(intVal);
   System.out.println(intVal);                 // => 10 
   //obj.PassByRefAndModify(ref intVal);
   //System.out.println(intVal);               // can't get it to say 20

   Counter obCounter = new Counter();
   obj.PassByValueAndModify(obCounter);
   System.out.println(obCounter.ToString());    // => Counter ID3541984 : Value 1
   //obj.PassByRefAndModify(ref obCounter);
   //Console.WriteLine(obCounter.ToString());   // no ref. but can make it 2 by repeating prev call
   obj.PassAndReassign(obCounter);
   System.out.println(obCounter.ToString());    // => Counter ID3541984 : Value 1
                                                // can't get it to say 5  
}
类MakeAPass
{
public void PassByValueAndModify(int i)
{i=20;}
//无法完成..请使用包装基元的Integer类
//public void PassByRefAndModify(ref int i)
public void PassByValueAndModify(计数器c)
{c.Increment();}
//同上。但没有ref关键字
//公共无效PassByRefAndModify(参考计数器c)
//这不能像在.net中那样完成
//公共无效密码REFANDREASSIGN(参考计数器c)
公共空行通道标志(c柜台)
{
c=新计数器();
对于(int i=0;i 10
//对象PassByRefAndModify(ref intVal);
//System.out.println(intVal);//不能让它说20
计数器obCounter=新计数器();
obj.PassByValueAndModify(对象计数器);
System.out.println(obCounter.ToString());//=>计数器ID3541984:值1
//对象PassByRefAndModify(参考对象计数器);
//Console.WriteLine(obCounter.ToString());//没有引用,但可以通过重复上一次调用使其变为2
obj.过道标志(obCounter);
System.out.println(obCounter.ToString());//=>计数器ID3541984:值1
//不能说是5
}

实际上,在Java中,引用是通过值传递的

在本例中,引用是一个
byte[]
对象。任何影响对象本身的更改都将从调用方方法中看到

但是,如果尝试替换引用,例如使用
newbyte[length]
,则只替换通过传递值获得的引用,因此不会更改调用方方法中的引用

以下是关于这个问题的有趣读物:


下面是一个具体的例子:

public class PassByValue
{
    public static void modifyArray(byte[] array)
    {
        System.out.println("Method Entry:  Length: " + array.length);
        array = new byte[16];
        System.out.println("Method Exit:   Length: " + array.length);
    }

    public static void main(String[] args)
    {
        byte[] array = new byte[8];
        System.out.println("Before Method: Length: " + array.length);
        modifyArray(array);
        System.out.println("After Method:  Length: " + array.length);
    }
}
此程序将在
main
方法中创建长度为
8
byte
数组,该数组将调用
modifyArray
方法,在该方法中,将创建长度为
16
的新
byte
数组

通过在
modifyArray
方法中创建一个新的
byte
数组,在返回到
main
方法时,
byte
数组的长度可能会是
16
,但是,运行此程序会揭示一些不同的情况:

Before Method: Length: 8
Method Entry:  Length: 8
Method Exit:   Length: 16
After Method:  Length: 8
modifyArray
方法返回时,
byte
数组的长度将恢复为
8
,而不是
16

为什么呢

这是因为
main
方法调用了
modifyArray
方法,并使用传递值
新字节[8]
发送了一个复制的引用
。当我们离开
modifyArray
时,对
新字节[16]
的引用已超出范围(最终将被垃圾收集)。但是,
main
方法仍然引用
新字节[8]
因为它只发送了复制的引用,而不是对引用的实际引用


这应该说明Java将使用pass-by-value传递引用。

您在方法中做什么?如果您只是填充一个现有数组,那么您不需要在.NET或Java中使用pass-by-reference语义。在这两种情况下,引用都将通过值传递,因此cal将看到对对象的更改这就好比告诉别人你家的地址,然后让他们送些东西给你——没问题

如果您真的想要通过引用传递语义,即调用方将看到对参数itse所做的任何更改
Before Method: Length: 8
Method Entry:  Length: 8
Method Exit:   Length: 16
After Method:  Length: 8
public void doSomething(byte[] data)
{
    for (int i=0; i < data.length; i++)
    {
        data[i] = (byte) i;
    }
}
public void createArray(byte[] data, int length)
{
    // Eek! Change to parameter won't get seen by caller
    data = new byte[length]; 
    for (int i=0; i < data.length; i++)
    {
        data[i] = (byte) i;
    }
}
public byte[] createArray(int length)
{
    byte[] data = new byte[length]; 
    for (int i=0; i < data.length; i++)
    {
        data[i] = (byte) i;
    }
    return data;
}
public class Holder<T>
{
    public T value; // Use a property in real code!
}

public void createArray(Holder<byte[]> holder, int length)
{
    holder.value = new byte[length]; 
    for (int i=0; i < length; i++)
    {
        holder.value[i] = (byte) i;
    }
}