web-dev-qa-db-ja.com

Javaで参照による呼び出しを行う方法

Javaはポインターをサポートしていないため、CおよびC++で行うようにJavaで参照によって関数を呼び出すことはできますか??

27
Shashi Bhushan

Javaでは、実際の参照渡しは不可能です。 Javaは、参照を含むすべての値を渡します。ただし、コンテナオブジェクトを使用してシミュレートできます。

これらのいずれかをメソッドパラメーターとして使用します。

  • 配列
  • コレクション
  • atomicXYZクラス

また、メソッドでコンテンツを変更すると、変更されたコンテンツは呼び出し側コンテキストで利用可能になります。


おっと、あなたは明らかにメソッドを参照によって呼び出すことを意味します。メソッドはJavaの第1レベルの市民ではないため、これはJavaでは不可能です。 これはJDK 8で変更される可能性があります ですが、当面はこの制限を回避するためにインターフェースを使用する必要があります。

public interface Foo{
    void doSomeThing();
}

public class SomeFoo implements Foo{
    public void doSomeThing(){
       System.out.println("foo");
    }
}

public class OtherFoo implements Foo{
    public void doSomeThing(){
       System.out.println("bar");
    }
}

コードでFooを使用して、SomeFooOtherFooで簡単に置き換えることができます。

37

Javaで参照による呼び出しを行う方法は?

Javaでは参照による呼び出しはできません。期間。何も近くに来ません。また、値による参照の受け渡しは、参照による呼び出しと同じではありません。

(実際の「参照による呼び出し」では、次のようなことができます。

void swap(ref int i, ref int j) { int tmp = *i; *i = *j; *j = tmp }

int a = 1;
int b = 2;
swap(a, b);

あなたは単にJavaでそれを行うことはできません。)


Javaはポインターをサポートしていません...

これは技術的には真実ですが、あなたがやろうとしていることの障害にはなりません。

Java doesサポートreferences。これは最も重要な点でポインターのようなものです。違いは、参照を計算したり、整数型との間で変換したりすることで、参照をメモリアドレスとして扱うことができないことです。また、JavaまたはJVMアーキテクチャには概念が存在しないため、変数への参照を作成できません。


CおよびC++で行うように、Javaの参照によって関数を呼び出すことはどのように可能ですか??

Javaでは、関数(メソッド)および関数への参照は値としてサポートされていません。したがって、それらを引数として渡すことはできず、変数に割り当てることもできません。

ただし、canは1つのインスタンスメソッドでクラスを定義し、関数参照の代わりにクラスのインスタンスを使用します。他の回答では、このアプローチの例を示しています。

11
Stephen C

通常、Javaで、これはインターフェイスを使用して解決されます。

Collections.sort(list, new Comparator() {

  @Override
  public int compareTo(Object o1, Object o2) {
  /// code
  }

});
3
Vladimir Ivanov

最善の方法は、アクションを実行するインターフェースを使用することです。

// Pass a Runnable which calls the task() method
executor.submit(new Runnable() {
    public void run() {
        task();
    }
});

public void task() { }

リフレクションを使用して任意のメソッドを呼び出すことができます

Method method = MyClass.class.getMethod("methodToCall", ParameterType.class);
result = method.invoke(object, args);
1
Peter Lawrey

Javaでは、プリミティブを除き、Objectをメソッド/関数に渡すのは常に参照です。例については、 Oli Charlesworthの答え を参照してください。

プリミティブ型の場合、配列を使用してラップできます。例:

public void foo(int[] in){
  in[0] = 2;
}

int[] byRef = new int[1];
byRef[0] = 1;
foo(byRef);
// ==> byRef[0] == 2.
1
Trung
package jgf;

public class TestJavaParams {

 public static void main(String[] args) {
    int[] counter1 = new int[1];
    counter1[0] = 0;
    System.out.println(counter1[0]);
    doAdd1(counter1);
    System.out.println(counter1[0]);
    int counter2 = 0;
    System.out.println(counter2);
    doAdd2(counter2);
    System.out.println(counter2);   
  }

  public static void doAdd1(int[] counter1) {
    counter1[0] += 1;
  }

  public static void doAdd2(int counter2) {
    counter2 += 1;
  }
}

出力は次のようになります。

0
1
0
0
1
JGFMK

Javaは、オブジェクトを使用した内部参照を許可します。この割り当てを記述すると、Obj o1 = new Obj(); Obj o2 = o1; o1とo2の両方が同じアドレスを指していることはどうなりますか。オブジェクトのスペースを操作すると、他のオブジェクトにも反映されます。

したがって、これを行うには、前述のように、配列、コレクションのいずれかを使用できます

0
Yash Bansal

http://www.javaworld.com/javaqa/2000-05/03-qa-0526-pass.html

Javaは参照によってオブジェクトを操作し、すべてのオブジェクト変数は参照です。ただし、Javaはメソッドの引数を参照で渡すのではなく、値で渡します。

0
Swetha D Murthy

From Java The Complete Reference by Herbert Shildt 9th edition:「オブジェクトをメソッドに渡すと、オブジェクトは事実上参照渡しで渡されるため、状況は劇的に変わります。保持クラス型の変数を作成するときは、オブジェクトへの参照を作成するだけなので、この参照をメソッドに渡すと、それを受け取るパラメーターは、参照するオブジェクトと同じオブジェクトを参照することになります。これは、事実上、オブジェクトが参照による呼び出しを使用してメソッドに渡されるかのように動作することを意味します。メソッド内のオブジェクトへの変更は、引数として使用されるオブジェクトに影響します。

package objectpassing;

public class PassObjectTest {

    public static void main(String[] args) {
        Obj1 o1 = new Obj1(9);
        System.out.println(o1.getA());
        o1.setA(3);
        System.out.println(o1.getA());
        System.out.println(sendObj1(o1).getA());
        System.out.println(o1.getA());
    }

public static Obj1 sendObj1(Obj1 o)
{
    o.setA(2);
    return o;
}


}

class Obj1
{
    private int a;

    Obj1(int num)
    {
        a=num;
    }

    void setA(int setnum)
    {
        a=setnum;
    }

    int getA()
    {
        return a;
    }
}

OP:9 3 2 2

GetA()の最後の呼び出しは、メソッドpublic static Obj1 sendObj1(Obj1 o)の呼び出しで元のオブジェクトフィールド 'a'が変更されたことを示しています。

0
Dave Black

Javaでは、値による呼び出しのみが許可されます。ただし、オブジェクトへの参照は、値による呼び出しを使用して、呼び出された関数に転送できます。これらの参照は、呼び出された関数のオブジェクトのデータを操作するために使用される場合、この変更は呼び出し元の関数でも表示されます。ポインターのように参照に対してポインター演算を行うことはできませんが、参照はC/C++で「*」演算子として機能するピリオド演算子を使用してオブジェクトのデータを指すことができます。

0
user3449128