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