Подтвердить что ты не робот

Как сделать вызов по ссылке в Java?

Так как Java не поддерживает указатели, как можно вызвать функцию по ссылке в Java, как в C и С++?

4b9b3361

Ответ 1

Реальная сквозная ссылка невозможна в Java. Java передает все по значению, включая ссылки. Но вы можете имитировать его с помощью Objects Objects.

Используйте любой из них в качестве параметра метода:

  • массив
  • a Коллекция
  • класс AtomicXYZ

И если вы измените его содержимое в методе, измененное содержимое будет доступно для вызывающего контекста.


К сожалению, вы, по-видимому, имеете в виду вызов метода по ссылке. Это также невозможно в Java, поскольку методы не являются гражданами первого уровня в 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 в своем коде, поэтому вы можете легко заменить SomeFoo на OtherFoo.

Ответ 2

  Как сделать вызов по ссылке в 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);
print("a is %s, b is %s\n", a, b);  // -> "a = 2, b = 1"

Вы просто не можете сделать это в Java.)


Поскольку Java не поддерживает указатели...

Хотя это технически верно, это не будет препятствием для того, что вы пытаетесь сделать.

Java поддерживает ссылки, которые в большинстве случаев похожи на указатели. Разница в том, что вы не можете рассматривать ссылки как адреса памяти, выполняя арифметику с ними, преобразовывая их в целочисленные типы и из них и так далее. И вы не можете создать ссылку на переменную, потому что концепция не существует в Java или архитектуре JVM.


Как можно вызвать функцию по ссылке в Java, как мы делаем это в C и C++??

Важное примечание: это не "звонок по ссылке". Это "вызов по значению" с использованием ссылки на функцию.

До Java 8 ссылки на функции не поддерживались как значения. Таким образом, вы не можете передавать их в качестве аргументов и не можете назначать их переменным.

Однако вы можете определить класс с помощью одного метода экземпляра и использовать экземпляр класса вместо ссылки на функцию. Другие ответы приводят примеры такого подхода.

Начиная с Java 8, ссылки на методы поддерживаются с использованием синтаксиса ::. Существует 4 вида ссылок на метод:

  • Ссылка на статический метод: ContainingClass::staticMethodName
  • Ссылка на метод экземпляра определенного объекта: containingObject::instanceMethodName
  • Ссылка на метод экземпляра произвольного объекта определенного типа: ContainingType::methodName
  • Ссылка на конструктор: ClassName::new

Ответ 3

Обычно в java это решается с помощью интерфейсов:

Collections.sort(list, new Comparator() {

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

});

Ответ 4

Лучший способ - использовать интерфейс, который выполняет действие.

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

Ответ 5

В Java, за исключением примитивов, передача объекта методу/функции всегда по ссылке. См. ответ Oli Charlesworth для примера.

Для примитивных типов вы можете обернуть его с помощью массива: Например:

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

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

Ответ 6

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

Ответ 7

JAVA позволяет внутреннюю ссылку с использованием объектов. Когда вы пишете это задание Obj o1 = новый Obj(); Obj o2 = o1; Что он делает, что и o1 и o2 указывают на один и тот же адрес. Манипулирование любым пространством объектов также отразится и на другом.

Чтобы сделать это, как уже упоминалось выше, вы можете использовать Array, Collections

Ответ 8

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

Java манипулирует объектами по ссылке, и все переменные объекта являются ссылками. Однако Java не передает аргументы метода по ссылке; он передает их по значению.

Ответ 9

Java допускает только вызов по значению. Однако ссылки на объекты могут быть переданы вызываемой функции, используя вызов по значению. Эти ссылки, если они используются для управления данными объекта в вызываемой функции, это изменение также будет видно в вызывающей функции. Мы не можем делать арифметику указателей на ссылках, как это делаем с указателями, но ссылки могут указывать на данные объекта, используя оператор периода, который функционирует как оператор "*" в C/С++.

Ответ 10

Из Java Полное обращение Герберта Шильдта 9-е издание: "Когда вы передаете объект методу, ситуация резко меняется, потому что объекты передаются тем, что эффективно является вызовом по ссылке. Имейте в виду, что когда вы создаете переменная типа класса, вы создаете только ссылку на объект. Таким образом, когда вы передаете эту ссылку на метод, параметр, который ее получает, будет ссылаться на тот же объект, что и объект, на который ссылается действие. Это фактически означает, что объекты действуют так, как если бы они передавались методам с помощью вызова по-референту ce. Изменения объекта внутри метода действительно влияют на объект, используемый в качестве аргумента."

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

FInal вызов getA() показывает, что исходное поле объекта 'a' было изменено в вызове метода public static Obj1 sendObj1 (Obj1 o).