次のようなもの:
参照例:
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#のref
およびout
キーワードのようなものはありません。
Javaでは値のみを渡すことができます。参照も値で渡されます。詳細については、 Jon Skeet の Javaで渡すパラメーター のページを参照してください。
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は値によってパラメーターを渡しますが、参照渡しを許可するメカニズムはありません。つまり、パラメーターが渡されるたびに、そのvalueが呼び出しを処理するスタックフレームにコピーされます。
ここで使用するvalueという用語には、少し説明が必要です。 Javaには、プリミティブとオブジェクトという2種類の変数があります。プリミティブの値はプリミティブ自体であり、オブジェクトの値はその参照です(参照されているオブジェクトの状態ではありません)。したがって、メソッド内の値を変更しても、スタック内の値のコピーのみが変更され、呼び出し元には表示されません。たとえば、2つの参照を受け取り、それらを(それらのコンテンツではなく)スワップする実際のスワップメソッドを実装する方法はありません。
他の多くの人と同様に、C#プロジェクトをJavaに変換する必要がありました。 outおよびref修飾子に関する完全な解決策がWebで見つかりませんでした。しかし、私は見つけた情報を取得し、それを拡張して要件を満たすための独自のクラスを作成することができました。コードを明確にするために、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();
}
}
実際、私が知っている限り、refもoutJava言語には同等のキーワードはありません。しかし、私はC#コードをJavaに変換しました--outパラメーターを使用し、今行ったことをアドバイスします。どんなオブジェクトでもラッパークラスにラップし、ラッパーオブジェクトインスタンスにラップされた値を次のように渡す必要があります。
ラッパークラス;
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メソッドがあります。
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;
}
そして、Javawrapper classの助けを借りてこのメソッドに相当するものは次のとおりです。
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;
}
このJavaコードで使用されるラッパークラスは以下のとおりです。
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;
}
}
公式には明らかにされていない3つのソリューション:
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