Something like the following:
ref example:
void changeString(ref String str) {
str = \"def\";
}
void main() {
String abc = \"abc\";
chan
java has no standard way of doing it. Most swaps will be made on the list that is packaged in the class. but there is an unofficial way to do it:
package Example;
import java.lang.reflect.Field;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Test{
private static <T> 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(String a,String b){
char[] tmp = a.toCharArray();
SetValue(a, b.toCharArray());
SetValue(b, tmp);
}
public static void main(String[] args) {
{
Integer d = 9;
Integer e = 8;
HoanVi(d, e);
System.out.println(d+" "+ e);
}
{
String d = "tai nguyen";
String e = "Thai nguyen";
permutation(d, e);
System.out.println(d+" "+ e);
}
}
}
No, Java doesn't have something like C#'s ref
and out
keywords for passing by reference.
You can only pass by value in Java. Even references are passed by value. See Jon Skeet's page about parameter passing in Java for more details.
To do something similar to ref
or out
you would have to wrap your parameters inside another object and pass that object reference in as a parameter.
Java passes parameters by value and doesn't have any mechanism to allow pass-by-reference. That means that whenever a parameter is passed, its value is copied into the stack frame handling the call.
The term value as I use it here needs a little clarification. In Java we have two kinds of variables - primitives and objects. A value of a primitive is the primitive itself, and the value of an object is its reference (and not the state of the object being referenced). Therefore, any change to the value inside the method will only change the copy of the value in the stack, and will not be seen by the caller. For example, there isn't any way to implement a real swap method, that receives two references and swaps them (not their content!).
Direct answer: No
But you can simulate reference with wrappers.
And do the following:
void changeString( _<String> str ) {
str.s("def");
}
void testRef() {
_<String> abc = new _<String>("abc");
changeString( abc );
out.println( abc ); // prints def
}
Out
void setString( _<String> ref ) {
str.s( "def" );
}
void testOut(){
_<String> abc = _<String>();
setString( abc );
out.println(abc); // prints def
}
And basically any other type such as:
_<Integer> one = new <Integer>(1);
addOneTo( one );
out.println( one ); // May print 2
Like many others, I needed to convert a C# project to Java. I did not find a complete solution on the web regarding out and ref modifiers. But, I was able to take the information I found, and expand upon it to create my own classes to fulfill the requirements. I wanted to make a distinction between ref and out parameters for code clarity. With the below classes, it is possible. May this information save others time and effort.
An example is included in the code below.
//*******************************************************************************************
//XOUT CLASS
//*******************************************************************************************
public class XOUT<T>
{
public XOBJ<T> Obj = null;
public XOUT(T value)
{
Obj = new XOBJ<T>(value);
}
public XOUT()
{
Obj = new XOBJ<T>();
}
public XOUT<T> Out()
{
return(this);
}
public XREF<T> Ref()
{
return(Obj.Ref());
}
};
//*******************************************************************************************
//XREF CLASS
//*******************************************************************************************
public class XREF<T>
{
public XOBJ<T> Obj = null;
public XREF(T value)
{
Obj = new XOBJ<T>(value);
}
public XREF()
{
Obj = new XOBJ<T>();
}
public XOUT<T> Out()
{
return(Obj.Out());
}
public XREF<T> 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<Integer> Total)
{
Total.Obj.Value += a;
}
//
// out parameter example
//
void Add(int a, int b, XOUT<Integer> ParmOut)
{
ParmOut.Obj.Value = a+b;
}
//
// XOBJ example
//
int XObjTest()
{
XOBJ<Integer> 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<T> {
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<T> Ref()
{
XREF<T> ref = new XREF<T>();
ref.Obj = this;
return(ref);
}
//
// Method: Out()
// Purpose: returns an Out Parameter Object using the XOBJ value
//
public XOUT<T> Out()
{
XOUT<T> out = new XOUT<T>();
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 String toString() {
return Value.toString();
}
@Override
public boolean equals(Object obj) {
return Value.equals(obj);
}
@Override
public int hashCode() {
return Value.hashCode();
}
}
Actually there is neither ref nor out keyword equivalent in Java language as far as I know. However I've just transformed a C# code into Java that uses out parameter and will advise what I've just done. You should wrap whatever object into a wrapper class and pass the values wrapped in wrapper object instance as follows;
Here is the Wrapper Class;
public class Wrapper {
public Object ref1; // use this as ref
public Object ref2; // use this as out
public Wrapper(Object ref1) {
this.ref1 = ref1;
}
}
And here is the test code;
public class Test {
public static void main(String[] args) {
String abc = "abc";
changeString(abc);
System.out.println("Initial object: " + abc); //wont print "def"
Wrapper w = new Wrapper(abc);
changeStringWithWrapper(w);
System.out.println("Updated object: " + w.ref1);
System.out.println("Out object: " + w.ref2);
}
// This won't work
public static void changeString(String str) {
str = "def";
}
// This will work
public static void changeStringWithWrapper(Wrapper w) {
w.ref1 = "def";
w.ref2 = "And this should be used as out!";
}
}
Here there is a C#.NET method that is using out keyword;
public bool Contains(T value)
{
BinaryTreeNode<T> parent;
return FindWithParent(value, out parent) != null;
}
private BinaryTreeNode<T> FindWithParent(T value, out BinaryTreeNode<T> parent)
{
BinaryTreeNode<T> 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;
}
And the Java equivalent of this method with the help of wrapper class is as follows;
public boolean contains(T value) {
BinaryTreeNodeGeneration<T> result = findWithParent(value);
return (result != null);
}
private BinaryTreeNodeGeneration<T> findWithParent(T value) {
BinaryTreeNode<T> current = head;
BinaryTreeNode<T> parent = null;
BinaryTreeNodeGeneration<T> resultGeneration = new BinaryTreeNodeGeneration<T>();
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;
}
And the wrapper class used in this Java code is as below;
public class BinaryTreeNodeGeneration<TNode extends Comparable<TNode>> {
private BinaryTreeNode<TNode> parentNode;
private BinaryTreeNode<TNode> childNode;
public BinaryTreeNodeGeneration() {
this.parentNode = null;
this.childNode = null;
}
public BinaryTreeNode<TNode> getParentNode() {
return parentNode;
}
public void setParentNode(BinaryTreeNode<TNode> parentNode) {
this.parentNode = parentNode;
}
public BinaryTreeNode<TNode> getChildNode() {
return childNode;
}
public void setChildNode(BinaryTreeNode<TNode> childNode) {
this.childNode = childNode;
}
}