Est-ce que Java a quelque chose comme les mots-clés de ref et out de C #?

Quelque chose comme ce qui suit:

Réf exemple:

void changeSsortingng(ref Ssortingng str) { str = "def"; } void main() { Ssortingng abc = "abc"; changeSsortingng(ref abc); System.out.println(abc); //prints "def" } 

exemple:

 void setSsortingng(out Ssortingng str) { str = "def"; } void main() { Ssortingng abc; changeSsortingng(out abc); System.out.println(abc); //prints "def" } 

Non, Java n’a pas quelque chose comme out mots clés ref et out C # pour passer par référence.

Vous ne pouvez transmettre que par valeur en Java. Même les références sont passées par valeur. Voir la page de Jon Skeet sur le passage des parameters en Java pour plus de détails.

Pour faire quelque chose de similaire à ref ou out vous devez envelopper vos parameters dans un autre object et passer cette référence d’object en paramètre.

Réponse directe: non

Mais vous pouvez simuler une référence avec des wrappers .

Et procédez comme suit:

 void changeSsortingng( _ str ) { str.s("def"); } void testRef() { _ abc = new _("abc"); changeSsortingng( abc ); out.println( abc ); // prints def } 

En dehors

 void setSsortingng( _ ref ) { str.s( "def" ); } void testOut(){ _ abc = _(); setSsortingng( abc ); out.println(abc); // prints def } 

Et fondamentalement tout autre type tel que:

 _ one = new (1); addOneTo( one ); out.println( one ); // May print 2 

Java transmet les parameters par valeur et ne dispose d’aucun mécanisme permettant d’autoriser les références. Cela signifie que chaque fois qu’un paramètre est transmis, sa valeur est copiée dans le cadre de la stack pour gérer l’appel.

Le terme valeur tel que je l’utilise ici nécessite un petit éclaircissement. En Java, nous avons deux types de variables: les primitives et les objects. La valeur d’une primitive est la primitive elle-même et la valeur d’un object est sa référence (et non l’état de l’object référencé). Par conséquent, toute modification de la valeur dans la méthode ne changera que la copie de la valeur dans la stack et ne sera pas vue par l’appelant. Par exemple, il n’y a aucun moyen d’implémenter une véritable méthode d’échange, qui reçoit deux références et les échange (pas leur contenu!).

En fait, pour autant que je sache, il n’y a pas de mot-clé ou de mot-clé équivalent en langage Java . Cependant, je viens de transformer un code C # en Java qui utilise des parameters et qui conseillera ce que je viens de faire. Vous devez envelopper tout object dans une classe wrapper et transmettre les valeurs contenues dans l’instance de l’object wrapper comme suit:

Un exemple simple d’utilisation de wrapper

Voici la classe Wrapper ;

 public class Wrapper { public Object ref1; // use this as ref public Object ref2; // use this as out public Wrapper(Object ref1) { this.ref1 = ref1; } } 

Et voici le code de test;

 public class Test { public static void main(Ssortingng[] args) { Ssortingng abc = "abc"; changeSsortingng(abc); System.out.println("Initial object: " + abc); //wont print "def" Wrapper w = new Wrapper(abc); changeSsortingngWithWrapper(w); System.out.println("Updated object: " + w.ref1); System.out.println("Out object: " + w.ref2); } // This won't work public static void changeSsortingng(Ssortingng str) { str = "def"; } // This will work public static void changeSsortingngWithWrapper(Wrapper w) { w.ref1 = "def"; w.ref2 = "And this should be used as out!"; } } 

Un exemple de monde réel

Méthode AC # .NET utilisant le paramètre out

Ici, il existe une méthode C # .NET qui utilise le mot clé out ;

 public bool Contains(T value) { BinaryTreeNode parent; return FindWithParent(value, out parent) != null; } private BinaryTreeNode FindWithParent(T value, out BinaryTreeNode parent) { BinaryTreeNode current = _head; parent = null; while(current != null) { int result = current.CompareTo(value); if (result > 0) { parent = current; current = current.Left; } else if (result < 0) { parent = current; current = current.Right; } else { break; } } return current; } 

Equivalent Java du code C # qui utilise le paramètre out

Et l'équivalent Java de cette méthode à l'aide de la classe wrapper est le suivant;

 public boolean contains(T value) { BinaryTreeNodeGeneration result = findWithParent(value); return (result != null); } private BinaryTreeNodeGeneration findWithParent(T value) { BinaryTreeNode current = head; BinaryTreeNode parent = null; BinaryTreeNodeGeneration resultGeneration = new BinaryTreeNodeGeneration(); resultGeneration.setParentNode(null); while(current != null) { int result = current.compareTo(value); if(result >0) { parent = current; current = current.left; } else if(result < 0) { parent = current; current = current.right; } else { break; } } resultGeneration.setChildNode(current); resultGeneration.setParentNode(parent); return resultGeneration; } 

Classe d'emballage

Et la classe wrapper utilisée dans ce code Java est comme ci-dessous;

 public class BinaryTreeNodeGeneration> { private BinaryTreeNode parentNode; private BinaryTreeNode childNode; public BinaryTreeNodeGeneration() { this.parentNode = null; this.childNode = null; } public BinaryTreeNode getParentNode() { return parentNode; } public void setParentNode(BinaryTreeNode parentNode) { this.parentNode = parentNode; } public BinaryTreeNode getChildNode() { return childNode; } public void setChildNode(BinaryTreeNode childNode) { this.childNode = childNode; } } 

Comme beaucoup d’autres, je devais convertir un projet C # en Java. Je n’ai pas trouvé de solution complète sur le Web concernant les modificateurs out et ref . Mais, j’ai pu prendre les informations que j’ai trouvées et les développer pour créer mes propres classes afin de répondre aux exigences. Je voulais faire une distinction entre les parameters ref et out pour la clarté du code. Avec les classes ci-dessous, c’est possible. Puisse cette information sauver du temps et des efforts.

Un exemple est inclus dans le code ci-dessous.

 //******************************************************************************************* //XOUT CLASS //******************************************************************************************* public class XOUT { public XOBJ Obj = null; public XOUT(T value) { Obj = new XOBJ(value); } public XOUT() { Obj = new XOBJ(); } public XOUT Out() { return(this); } public XREF Ref() { return(Obj.Ref()); } }; //******************************************************************************************* //XREF CLASS //******************************************************************************************* public class XREF { public XOBJ Obj = null; public XREF(T value) { Obj = new XOBJ(value); } public XREF() { Obj = new XOBJ(); } public XOUT Out() { return(Obj.Out()); } public XREF Ref() { return(this); } }; //******************************************************************************************* //XOBJ CLASS //******************************************************************************************* /** * * @author jsimms */ /* XOBJ is the base object that houses the value. XREF and XOUT are classes that internally use XOBJ. The classes XOBJ, XREF, and XOUT have methods that allow the object to be used as XREF or XOUT parameter; This is important, because objects of these types are interchangeable. See Method: XXX.Ref() XXX.Out() The below example shows how to use XOBJ, XREF, and XOUT; // // Reference parameter example // void AddToTotal(int a, XREF Total) { Total.Obj.Value += a; } // // out parameter example // void Add(int a, int b, XOUT ParmOut) { ParmOut.Obj.Value = a+b; } // // XOBJ example // int XObjTest() { XOBJ Total = new XOBJ<>(0); Add(1, 2, Total.Out()); // Example of using out parameter AddToTotal(1,Total.Ref()); // Example of using ref parameter return(Total.Value); } */ public class XOBJ { public T Value; public XOBJ() { } public XOBJ(T value) { this.Value = value; } // // Method: Ref() // Purpose: returns a Reference Parameter object using the XOBJ value // public XREF Ref() { XREF ref = new XREF(); ref.Obj = this; return(ref); } // // Method: Out() // Purpose: returns an Out Parameter Object using the XOBJ value // public XOUT Out() { XOUT out = new XOUT(); out.Obj = this; return(out); } // // Method get() // Purpose: returns the value // Note: Because this is combersome to edit in the code, // the Value object has been made public // public T get() { return Value; } // // Method get() // Purpose: sets the value // Note: Because this is combersome to edit in the code, // the Value object has been made public // public void set(T anotherValue) { Value = anotherValue; } @Override public Ssortingng toSsortingng() { return Value.toSsortingng(); } @Override public boolean equals(Object obj) { return Value.equals(obj); } @Override public int hashCode() { return Value.hashCode(); } } 

Trois solutions non officiellement, explicitement mentionnées:

 ArrayList doThings() { // } void doThings(ArrayList list) { // } Pair doThings() { // } 

Pour Pair, je recommanderais: https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/Pair.html

Java n’a pas de méthode standard pour le faire. La plupart des échanges seront effectués sur la liste qui est incluse dans la classe. mais il existe une façon non officielle de le faire:

 package Example; import java.lang.reflect.Field; import java.util.logging.Level; import java.util.logging.Logger; public class Test{ private static  void SetValue(T obj,T value){ try { Field f = obj.getClass().getDeclaredField("value"); f.setAccessible(true); f.set(obj,value); } catch (IllegalAccessException | IllegalArgumentException | NoSuchFieldException | SecurityException ex) { Logger.getLogger(CautrucjavaCanBan.class.getName()).log(Level.SEVERE, null, ex); } } private static void permutation(Integer a,Integer b){ Integer tmp = new Integer(a); SetValue(a, b); SetValue(b, tmp); } private static void permutation(Ssortingng a,Ssortingng b){ char[] tmp = a.toCharArray(); SetValue(a, b.toCharArray()); SetValue(b, tmp); } public static void main(Ssortingng[] args) { { Integer d = 9; Integer e = 8; HoanVi(d, e); System.out.println(d+" "+ e); } { Ssortingng d = "tai nguyen"; Ssortingng e = "Thai nguyen"; permutation(d, e); System.out.println(d+" "+ e); } } }