Pergunta

Você pode fazer isso no .NET usando a palavra -chave "ref". Existe alguma maneira de fazê -lo em Java?

Foi útil?

Solução

O que você está fazendo em seu método? Se você está apenas preenchendo uma matriz existente, não precisa de semântica de passagem por referência-no .NET ou no Java. Nos dois casos, a referência será passada por valor - portanto, mudanças no objeto será visível pelo chamador. É como dizer a alguém o endereço da sua casa e pedir que eles entregassem algo a ela - sem problemas.

Se você verdade Deseja semântica de passagem por referência, ou seja, o chamador verá quaisquer alterações feitas no próprio parâmetro, por exemplo, definindo-o como nulo ou uma referência a uma matriz de bytes diferente, então qualquer método precisa retornar o novo valor ou você precisa passar Uma referência a algum tipo de "suporte" que contém uma referência à matriz de bytes, e que pode ter a referência (possivelmente alterada) capturada mais tarde.

Em outras palavras, se o seu método parece gostar disso:

public void doSomething(byte[] data)
{
    for (int i=0; i < data.length; i++)
    {
        data[i] = (byte) i;
    }
}

Então você está bem. Se o seu método se parece com o seguinte:

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

Então você precisa alterá -lo para:

public byte[] createArray(int length)
{
    byte[] data = new byte[length]; 
    for (int i=0; i < data.length; i++)
    {
        data[i] = (byte) i;
    }
    return data;
}

ou:

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

Para mais detalhes, leia Parâmetro Passando em C# e Parâmetro Passando em Java. (O primeiro é melhor escrito que o último, receio. Um dia vou fazer uma atualização.)

Outras dicas

Na verdade, em Java, o As referências são passadas por valor.

Nesse caso, a referência é um byte[] objeto. Quaisquer alterações que afetem o objeto em si serão vistas do método do chamador.

No entanto, se você tentar substituir a referência, por exemplo, usando new byte[length], você está apenas substituindo a referência que obteve por valor por valor, para não estar alterando a referência no método do chamador.

Aqui está uma leitura interessante sobre esta edição: Java é damita de passe por valor!


Aqui está um exemplo concreto:

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

Este programa criará um byte Matriz de comprimento 8 no main método, que chamará o modifyArray método, onde o novo byte Matriz de comprimento 16 é criado.

Pode parecer que, criando um novo byte Array no modifyArray método, que o comprimento do byte Array ao retornar ao main Método será 16, no entanto, a execução deste programa revela algo diferente:

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

O comprimento do byte Array ao retornar do modifyArray método reverte para 8 ao invés de 16.

Por que é que?

Isso é porque o main Método chamado modifyArray método e enviado uma referência copiada ao new byte[8] usando Pass-por valor. Então o modifyArray método jogou fora a referência copiada criando um new byte[16]. Quando saímos modifyArray, a referência ao new byte[16] está fora de escopo (e eventualmente será coletado de lixo.) No entanto, o main o método ainda tem referência ao new byte[8] apenas como isso enviou a referência copiada e não uma referência real à referência.

Isso deve demonstrar que o Java passará a referência usando o valor por passes.

Java usa o passe por valor para argumentos de método.

  • Primitivos (int, booleano, etc.) são casos especiais em java .. não objetos em si. Nesse caso, uma cópia do primitivo (argumento) é transmitida para a função. Isso goma bem com o passe pela teoria do valor.
  • Para objetos, o que acontece é que o ref para o objeto é passado pelo valor (uma cópia da referência é feita e não o objeto) ... mas ambas as referências apontam para o mesmo objeto. Portanto, se você modificar um parâmetro de objeto em um método, o objeto real será modificado.

Este artigo deve ajudá -lo ..http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-sass.html

Quanto à pergunta do OP, basta passar na referência à matriz de byte [] ao método. O resultado líquido seria semelhante a passar por referência. Se você modificar a matriz de bytes, o chamador poderá ver a execução do método post de alterações.

Atualizar para reprimir a resistência :) => indica saída

.NET TERRA

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
}

Terra java

Menores menores reqd: use hashcode () e + para concatar strings em contador.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  
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top