source

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

factcode 2022. 9. 16. 23:00
반응형

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

의 C#, C#의 C#은 없습니다.ref ★★★★★★★★★★★★★★★★★」out키워드를 지정합니다.

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

일을 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

사실 자바 언어에는 ref 키워드도 out 키워드도 없는 으로 알고 있습니다.다만, 방금 C# 코드를 파라미터를 사용하는 Java로 변환했습니다.이것에 의해, 지금까지의 조작이 통지됩니다.임의의 오브젝트를 래퍼 클래스로 랩하고 래퍼 오브젝트인스턴스로 랩된 값을 다음과 같이 전달해야 합니다.

래퍼 사용의 간단한 예

래퍼 클래스는 다음과 같습니다.

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 파라미터를 사용하는 C#.NET 메서드

여기 C#이 있습니다.out 키워드를 사용하는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;
}

Java out 파라미터를 사용하는 C# 코드에 상당합니다.

또한 래퍼 클래스의 도움을 받는 이 메서드에 해당하는 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는 매개 변수를 값별로 전달하며 pass-by-reference를 허용하는 메커니즘이 없습니다.즉, 파라미터가 전달될 때마다 그 이 콜을 처리하는 스택프레임으로 복사됩니다.

여기서 사용하는 값이라는 용어는 좀 더 명확히 해야 합니다.Java에는 두 가지 변수, 즉 원시 변수와 객체가 있습니다.프리미티브의 값은 프리미티브 그 자체이며 오브젝트의 값은 참조되는 오브젝트의 상태가 아닙니다.따라서 메서드 내의 값을 변경하면 스택 내의 값 복사본만 변경되며 발신자에게는 표시되지 않습니다.예를 들어, 2개의 참조를 수신하여 (콘텐츠가 아닌) 스왑하는 실제 스왑 방식을 구현할 수 있는 방법은 없습니다.

다른 많은 사람들과 마찬가지로 C# 프로젝트를 Java로 변환해야 했습니다.웹에서 out 및 ref 수식어에 대한 완전한 해결책을 찾지 못했습니다.하지만, 저는 제가 발견한 정보를 가지고, 그 정보를 확장하여 제 자신의 수업들을 만들어서 요건을 충족시킬 수 있었습니다.코드 명확성을 위해 ref 파라미터와 out 파라미터를 구별하고 싶었습니다.아래의 수업으로 가능합니다.이 정보를 통해 다른 사람의 시간과 노력을 절약할 수 있기를 바랍니다.

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

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

쌍에 대해서는 https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/Pair.html을 권장합니다.

java에는 표준적인 방법이 없습니다.대부분의 스왑은 클래스에 패키지화된 목록에서 이루어집니다.하지만 비공식적인 방법이 있습니다.

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

}

언급URL : https://stackoverflow.com/questions/2806545/does-java-have-something-like-cs-ref-and-out-keywords

반응형