문제

키워드 "Ref"를 사용하여 .NET에서 수행 할 수 있습니다. Java에서 그렇게 할 방법이 있습니까?

도움이 되었습니까?

해결책

방법에서 무엇을하고 있습니까? 기존 배열을 채우는 것만으로도 .NET 또는 Java에서는 추천 시맨틱이 필요하지 않습니다. 두 경우 모두 참조는 가치에 따라 전달됩니다. 물체 발신자가 볼 수 있습니다. 그것은 누군가에게 집의 주소를 말하고 그들에게 무언가를 전달하도록 요청하는 것과 같습니다.

만약 너라면 진짜 Pass-by-reference Semantics를 원합니다. 즉, 발신자는 매개 변수 자체에 대한 변경 사항과 예를 들어 NULL 또는 다른 바이트 배열에 대한 참조를 설정 한 다음 메소드가 새 값을 반환해야하거나 통과해야합니다. 바이트 어레이에 대한 참조를 포함하고 나중에 (아마도 변경된) 참조를 가져올 수있는 일종의 "홀더"에 대한 참조.

다시 말해, 방법이 좋아하는 경우 :

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;
    }
}

자세한 내용은 읽으십시오 C#에서 전달되는 매개 변수 그리고 Java로 통과하는 매개 변수. (전자는 후자보다 더 잘 쓰여 있습니다. 두려워합니다. 언젠가는 업데이트를 할 것입니다.)

다른 팁

실제로 Java에서 참조는 가치가 전달됩니다.

이 경우 참조는 a입니다 byte[] 물체. 객체 자체에 영향을 미치는 모든 변경 사항은 발신자 메소드에서 볼 수 있습니다.

그러나 참조를 교체하려고하면 예를 들어 new byte[length], 귀하는 Pass-By-Value로 얻은 참조 만 교체하므로 발신자 메소드에서 참조를 변경하지 않습니다.

이 문제에 대한 흥미로운 읽기는 다음과 같습니다. Java는 패스 별 가치가 있습니다!


구체적인 예는 다음과 같습니다.

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

이 프로그램은 a를 만들 것입니다 byte 길이의 배열 8 에서 main 메소드를 호출합니다 modifyArray 새로운 방법 byte 길이의 배열 16 생성됩니다.

새로운 것을 만들어 보일 수 있습니다 byte 배열 modifyArray 방법, 길이 byte 돌아올 때 배열 main 방법이 될 것입니다 16, 그러나이 프로그램을 실행하는 것은 다른 것을 보여줍니다.

Before Method: Length: 8
Method Entry:  Length: 8
Method Exit:   Length: 16
After Method:  Length: 8

길이 byte 에서 돌아올 때 배열 modifyArray 메소드가 되돌아갑니다 8 대신에 16.

왜 그런 겁니까?

그 때문입니다 main 메소드라고 불렀습니다 modifyArray 방법 및 전송 복사 된 참조 new byte[8] 사용하여 통과 값. 그런 다음 modifyArray 방법 a new byte[16]. 우리가 떠날 때까지 modifyArray,에 대한 참조 new byte[16] 범위를 벗어났습니다 (그리고 결국 쓰레기가 수집 될 것입니다.) 그러나 main 메소드는 여전히에 대한 참조를 가지고 있습니다 new byte[8] 그대로 복사 된 참조를 보냈습니다 참조에 대한 실제 참조가 아닙니다.

Java는 Pass-By-Value를 사용하여 기준을 통과시킬 것임을 입증해야합니다.

Java는 메소드 인수에 대한 값을 사용합니다.

  • 기초 요소 (int, boolean 등)은 Java의 특별한 경우입니다. 이 경우 원시 (인수)의 사본이 함수로 전달됩니다. 이 젤은 합격 값 이론과 잘 어울립니다.
  • 객체의 경우, 객체에 대한 심판이 값으로 전달된다는 것입니다 (참조 사본은 객체가 아닌 참조 사본이 만들어집니다). 그러나 두 참조는 동일한 객체를 가리 킵니다. 따라서 메소드에서 객체 매개 변수를 수정하면 실제 객체가 수정됩니다.

이 기사는 당신을 도와 줄 것입니다 ..http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html

OP의 질문에 관해서는 바이트 [] 배열을 메소드에 참조하십시오. 순 결과는 참조 별 패스와 유사합니다. 바이트 배열을 수정하면 발신자가 메서드 실행 후 변경 사항을 볼 수 있습니다.

저항을 진압하기 위해 업데이트 :) => 출력을 나타냅니다

.NET Land

class Counter
{
  private int m_count = 0;
  public override string  ToString()
  {
     return String.Format("Counter ID{0} : Value {1}", this.GetHashCode(), m_count);
  }
  public void Increment()
  {  m_count++;  }
}
class MakeAPass
{
   public void PassByValueAndModify(int i)
   {   i = 20;    }

   public void PassByRefAndModify(ref int i)
   {   i = 20;   }

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

   public void PassByRefAndModify(ref Counter c)
   {   c.Increment();   }

   public void PassByRefAndReassign(ref Counter c)
   {
      c = new Counter();
      for (int i=0; i<5; ++i)
         c.Increment();
   }
}

static void Main(string[] args)
{
   MakeAPass obj = new MakeAPass();
   int intVal = 10;
   obj.PassByValueAndModify(intVal);
   Console.WriteLine(intVal);              // => 10
   obj.PassByRefAndModify(ref intVal);
   Console.WriteLine(intVal);              // => 20

   Counter obCounter = new Counter();
   obj.PassByValueAndModify(obCounter);
   Console.WriteLine(obCounter.ToString());  // => Counter ID58225482 : Value 1
   obj.PassByRefAndModify(ref obCounter);
   Console.WriteLine(obCounter.ToString());  // => Counter ID58225482 : Value 2
   obj.PassByRefAndReassign(ref obCounter);
   Console.WriteLine(obCounter.ToString());  // => Counter ID54267293 : Value 5
}

자바 땅

Minor Mods Reqd : hashcode ()를 사용하여 Coun

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  
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top