Передача строки по ссылке в Java?

Я сам этого не пробовал, но вы можете попробовать реализовать метод application:handleOpenURL: в делетете приложения - похоже, что все запросы openURL проходят через этот обратный вызов.

146
задан nbro 27 May 2015 в 21:09
поделиться

8 ответов

You have three options:

  1. Use a StringBuilder:

    StringBuilder zText = new StringBuilder ();
    void fillString(StringBuilder zText) { zText.append ("foo"); }
    
  2. Создайте контейнерный класс и передайте экземпляр контейнера вашему методу:

     открытый класс Контейнер {public String data; }
    void fillString (Контейнер c) {c.data + = "foo"; }
    
  3. Создайте массив:

     new String [] zText = new String [1];
    zText [0] = "";
    
    void fillString (String [] zText) {zText [0] + = "foo"; }
    

С точки зрения производительности StringBuilder обычно является лучшим вариантом.

188
ответ дан 23 November 2019 в 22:23
поделиться

String - это специальный класс в Java. Это Thread Safe, что означает: «После создания экземпляра String содержимое экземпляра String никогда не изменится».

Вот что происходит для

 zText += "foo";

Во-первых, компилятор Java получит значение экземпляра zText String. , затем создайте новый экземпляр String со значением zText с добавлением «foo». Итак, вы знаете, почему экземпляр, на который указывает zText, не изменился. Это совершенно новый экземпляр. Фактически, даже String «foo» является новым экземпляром String. Итак, для этого оператора Java создаст два экземпляра String, один - «foo», другой - значение zText append «foo». Правило простое: значение экземпляра String никогда не будет изменено.

Для метода fillString вы можете использовать StringBuffer в качестве параметра или изменить его следующим образом:

String fillString(String zText) {
    return zText += "foo";
}
2
ответ дан 23 November 2019 в 22:23
поделиться

Strings are immutable in Java.

1
ответ дан 23 November 2019 в 22:23
поделиться

java.lang.String is immutable.

I hate pasting URLs but https://docs.oracle.com/javase/10/docs/api/java/lang/String.html is essential for you to read and understand if you're in java-land.

18
ответ дан 23 November 2019 в 22:23
поделиться

Все аргументы в Java передаются по значению . Когда вы передаете String функции, переданное значение является ссылкой на объект String, но вы не можете изменить эту ссылку, а базовый объект String неизменен.

Назначение

zText += foo;

эквивалентно:

zText = new String(zText + "foo");

То есть (локально) переназначает параметр zText как новую ссылку, которая указывает на новую ячейку памяти, в которой находится новый Строка , которая содержит исходное содержимое zText с добавленным «foo» .

Исходный объект не изменяется, а main () метод ' s локальная переменная zText по-прежнему указывает на исходную (пустую) строку.

class StringFiller {
  static void fillString(String zText) {
    zText += "foo";
    System.out.println("Local value: " + zText);
  }

  public static void main(String[] args) {
    String zText = "";
    System.out.println("Original value: " + zText);
    fillString(zText);
    System.out.println("Final value: " + zText);
  }
}

выводит:

Original value:
Local value: foo
Final value:

Если вы хотите изменить строку, вы можете, как отмечалось, использовать StringBuilder или другое некоторый контейнер (массив или AtomicReference или пользовательский класс контейнера), который дает вам дополнительный уровень косвенного обращения к указателям. В качестве альтернативы, просто верните новое значение и присвойте его:

class StringFiller2 {
  static String fillString(String zText) {
    zText += "foo";
    System.out.println("Local value: " + zText);
    return zText;
  }

  public static void main(String[] args) {
    String zText = "";
    System.out.println("Original value: " + zText);
    zText = fillString(zText);
    System.out.println("Final value: " + zText);
  }
}

печатает:

Original value:
Local value: foo
Final value: foo

Это, вероятно, наиболее похожее на Java решение в общем случае - см. Пункт Эффективная Java «Поддерживайте неизменность».

Однако, как уже отмечалось, StringBuilder часто дает вам лучшую производительность - если вам нужно выполнить много операций добавления, особенно внутри цикла, используйте StringBuilder .

Но попробуйте передать неизменные строки , а не изменяемые StringBuilders , если можете - ваш код будет легче читать и легче поддерживать. Подумайте о том, чтобы сделать ваши параметры final и сконфигурировать вашу среду IDE, чтобы предупреждать вас, когда вы переназначаете параметр метода на новое значение.

6
ответ дан 23 November 2019 в 22:23
поделиться

объекты передаются по ссылке, примитивы передаются по значению.

Строка не является примитивом, это объект, и это особый случай объекта.

Это сделано для экономии памяти. В JVM есть пул строк. Для каждой созданной строки JVM будет пытаться увидеть, существует ли такая же строка в пуле строк, и указывать на нее, если она уже была.

public class TestString
{
    private static String a = "hello world";
    private static String b = "hello world";
    private static String c = "hello " + "world";
    private static String d = new String("hello world");

    private static Object o1 = new Object();
    private static Object o2 = new Object();

    public static void main(String[] args)
    {
        System.out.println("a==b:"+(a == b));
        System.out.println("a==c:"+(a == c));
        System.out.println("a==d:"+(a == d));
        System.out.println("a.equals(d):"+(a.equals(d)));
        System.out.println("o1==o2:"+(o1 == o2));

        passString(a);
        passString(d);
    }

    public static void passString(String s)
    {
        System.out.println("passString:"+(a == s));
    }
}

/ * OUTPUT * /

a==b:true
a==c:true
a==d:false
a.equals(d):true
o1==o2:false
passString:true
passString:false

== проверяет адрес памяти ( ссылка), а .equals проверяет содержимое (значение)

7
ответ дан 23 November 2019 в 22:23
поделиться

В Java ничего не передается по ссылке . Все передается по значению . Ссылки на объекты передаются по значению. Кроме того, строки неизменяемы . Итак, когда вы добавляете к переданной строке, вы просто получаете новую строку. Вы можете использовать возвращаемое значение или вместо этого передать StringBuffer.

82
ответ дан 23 November 2019 в 22:23
поделиться

What is happening is that the reference is passed by value, i.e., a copy of the reference is passed. Nothing in java is passed by reference, and since a string is immutable, that assignment creates a new string object that the copy of the reference now points to. The original reference still points to the empty string.

This would be the same for any object, i.e., setting it to a new value in a method. The example below just makes what is going on more obvious, but concatenating a string is really the same thing.

void foo( object o )
{
    o = new Object( );  // original reference still points to old value on the heap
}
50
ответ дан 23 November 2019 в 22:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: