[java] Java에는 C #의 ref 및 out 키워드와 같은 것이 있습니까?

다음과 같은 것 :

참조 예 :

void changeString(ref String str) {
    str = "def";
}

void main() {
    String abc = "abc";
    changeString(ref abc);
    System.out.println(abc); //prints "def"
}

아웃 예 :

void changeString(out String str) {
    str = "def";
}

void main() {
    String abc;
    changeString(out abc);
    System.out.println(abc); //prints "def"
}



답변

아니요, Java에는 참조로 전달하기위한 C # refout키워드 와 같은 것이 없습니다 .

Java에서는 값으로 만 전달할 수 있습니다. 참조조차도 값으로 전달됩니다. 자세한 내용 은 Java에서 매개 변수 전달에 대한 Jon Skeet 의 페이지 를 참조하십시오.

비슷한 수행 ref또는 out다른 개체 내부에 매개 변수를 포장하고 매개 변수로 해당 개체의 참조를 전달해야합니다.


답변

직접 답변 : 아니요

그러나 래퍼로 참조를 시뮬레이션 할 수 있습니다 .

그리고 다음을 수행하십시오.

void changeString( _<String> str ) {
    str.s("def");
}

void testRef() {
     _<String> abc = new _<String>("abc");
     changeString( abc );
     out.println( abc ); // prints def
}

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

그리고 기본적으로 다음과 같은 다른 유형 :

_<Integer> one = new <Integer>(1);
addOneTo( one );

out.println( one ); // May print 2


답변

실제로 내가 아는 한 Java 언어 에는 ref 또는 out 키워드 가 없습니다 . 그러나 저는 매개 변수 를 사용 하는 JavaC # 코드를 변환했으며 방금 수행 한 작업을 조언합니다. 어떤 객체 든 래퍼 클래스로 래핑하고 다음과 같이 래퍼 객체 인스턴스에 래핑 된 값을 전달해야합니다.

래퍼 사용에 대한 간단한 예

다음은 래퍼 클래스입니다 .

public class Wrapper {
    public Object ref1; // use this as ref
    public Object ref2; // use this as out

    public Wrapper(Object ref1) {
        this.ref1 = ref1;
    }
}

그리고 여기에 테스트 코드가 있습니다.

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

}

실제 사례

out 매개 변수를 사용하는 AC # .NET 메서드

여기에 out 키워드를 사용 하는 C # .NET 메서드가 있습니다 .

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

out 매개 변수를 사용하는 C # 코드에 해당하는 Java

그리고 래퍼 클래스 의 도움으로이 메서드에 해당 하는 Java 는 다음과 같습니다.

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

래퍼 클래스

그리고이 자바 코드에서 사용되는 래퍼 클래스 는 다음과 같습니다.

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

}


답변

Java는 매개 변수를 값으로 전달하며 참조에 의한 전달을 허용하는 메커니즘이 없습니다. 즉, 매개 변수가 전달 될 때마다 해당 이 호출을 처리하는 스택 프레임에 복사됩니다.

여기서 사용하는 용어 은 약간의 설명이 필요합니다. 자바에는 두 가지 종류의 변수가 있습니다. 프리미티브와 객체입니다. 프리미티브의 값은 프리미티브 자체이고 객체의 값은 참조 (참조되는 객체의 상태가 아님)입니다. 따라서 메서드 내부의 값을 변경하면 스택의 값 복사본 만 변경되며 호출자에게는 표시되지 않습니다. 예를 들어 실제 스왑 메서드를 구현할 수있는 방법이 없습니다. 두 참조를 받고이를 스왑합니다 (그 내용이 아닙니다!).


답변

다른 많은 프로젝트와 마찬가지로 C # 프로젝트를 Java로 변환해야했습니다. 웹에서 outref 수정 자 에 관한 완전한 솔루션을 찾지 못했습니다 . 그러나 나는 내가 찾은 정보를 가지고 그것을 확장하여 요구 사항을 충족시키기 위해 나만의 수업을 만들 수있었습니다. 코드 명확성을 위해 refout 매개 변수를 구분하고 싶었습니다 . 아래 수업으로 가능합니다. 이 정보가 다른 사람들의 시간과 노력을 절약하기를 바랍니다.

아래 코드에 예제가 포함되어 있습니다.

//*******************************************************************************************
//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();
    }
}


답변

공식적으로 명시되지 않은 세 가지 솔루션 :

ArrayList<String> doThings() {
  //
}

void doThings(ArrayList<String> list) {
  //
}

Pair<String, String> doThings() {
  //
}

Pair의 경우 다음을 권장합니다. https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/Pair.html


답변

자바에는 표준 방식이 없습니다. 대부분의 스왑은 클래스에 포함 된 목록에서 이루어집니다. 그러나 비공식적 인 방법이 있습니다.

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

}