Actuellement, il n'y a ni de mot-clé ref ni de mot-clé out équivalent dans le langage Java à ma connaissance. Cependant, je viens de transformer un code C# en Java qui utilise le paramètre out et je vais vous expliquer ce que j'ai fait. Vous devez encapsuler n'importe quel objet dans une classe wrapper et passer les valeurs encapsulées dans une instance d'objet wrapper comme suit;
Un exemple simple d'utilisation d'un wrapper
Voici la classe wrapper;
public class Wrapper {
public Object ref1; // utilisez ceci comme ref
public Object ref2; // utilisez ceci comme out
public Wrapper(Object ref1) {
this.ref1 = ref1;
}
}
Et voici le code de test;
public class Test {
public static void main(String[] args) {
String abc = "abc";
changeString(abc);
System.out.println("Objet initial: " + abc); // ne va pas afficher "def"
Wrapper w = new Wrapper(abc);
changeStringWithWrapper(w);
System.out.println("Objet mis à jour: " + w.ref1);
System.out.println("Objet out: " + w.ref2);
}
// Cela ne fonctionnera pas
public static void changeString(String str) {
str = "def";
}
// Cela fonctionnera
public static void changeStringWithWrapper(Wrapper w) {
w.ref1 = "def";
w.ref2 = "Et ceci devrait être utilisé comme out!";
}
}
Un exemple concret
Une méthode C#.NET utilisant le paramètre out
Voici 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;
}
Équivalent en Java du code C# utilisant le paramètre out
Et l'équivalent en Java de cette méthode avec 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 wrapper
Et la classe wrapper utilisée dans ce code Java est la suivante;
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;
}
}
1 votes
Possible duplicate de Puis-je passer des paramètres par référence en Java?
5 votes
IMO tu ne rates pas grand-chose. La seule fois où j'utilise
ref
ouout
en C# est lorsque j'utilise un motif commeTryParse()
, où la méthode renvoie un résultat booléen, et le seul moyen d'obtenir une valeur analysée en est par l'utilisation deref
ouout
.4 votes
Devine quoi, c'est exactement ce dont j'ai besoin d'utiliser! ;)
1 votes
L'autre façon de le faire est de renvoyer un objet composite avec à la fois le statut et une valeur nullable à l'intérieur. Mais j'avoue que c'est un peu Rube Goldberg-ish.
1 votes
Rien de mal à retourner un objet composite, s'il n'y avait qu'un qui était prédéfini et utilisable (c.-à-d. les tuples). Mais attendez, il faudrait que les génériques non effacés fonctionnent avec les types primitifs pour être efficace :)
0 votes
Je pense que renvoyer une valeur en cas de succès et lancer une exception en cas d'échec est la manière habituelle de le faire en Java.
0 votes
En C#, ref et out sont des choses que nous devrions éviter
0 votes
@Sean Pourquoi? Si vous avez une routine qui doit renvoyer par exemple deux entiers, alors utiliser des paramètres de sortie est parfaitement acceptable.
0 votes
@Karlth vous avez plusieurs options pour renvoyer deux entiers à partir d'une méthode, et les paramètres de sortie ne sont certainement pas une bonne option
0 votes
@Sean Quelles options ? La seule possibilité que je vois est de créer une classe séparée pour les valeurs et de la retourner, ce qui est beaucoup de paperasserie pour une fonctionnalité simple. D'autres options ?
0 votes
@Karlth À mon avis, l'utilisation d'un tuple ou d'un type enregistrement est une meilleure option pour renvoyer plusieurs valeurs