← Назад к вопросам
Предсказать вывод: передача строки в метод
1.3 Junior🔥 121 комментариев
#ООП#Основы Java
Условие
Какой результат выведет следующий код?
void foo() {
String m = "Hello";
System.out.print(m);
bar(m);
System.out.print(m);
}
void bar(String m) {
m += " World!";
}
Вопросы
- Что выведет программа?
- Почему результат именно такой?
- Как изменить код, чтобы получить "HelloHello World!"?
Подсказка
Обратите внимание на неизменяемость (immutability) строк в Java и на передачу параметров по значению.
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Предсказать вывод: передача строки в метод
Ответ
Программа выведет: HelloHello
Почему именно HelloHello?
Это один из ключевых вопросов, тестирующих понимание:
- Неизменяемости строк (String immutability)
- Передачи параметров по значению (pass-by-value)
- Ссылки на объекты в Java
Объяснение шаг за шагом
void foo() {
String m = "Hello"; // m указывает на объект "Hello"
System.out.print(m); // Выводит: Hello
bar(m); // Передаём ССЫЛКУ на m
System.out.print(m); // Выводит: Hello (не изменилось!)
}
void bar(String m) {
m += " World!"; // m ПЕРЕАССОЦИИРУЕТСЯ на новый объект
}
Ключевой момент: в методе bar() строка m переассоциируется на новый объект, созданный операцией конкатенации. Но это не влияет на переменную m в методе foo().
Внутреннее представление в памяти
Шаг 1: String m = "Hello";
┌─────────────────────────────┐
│ Stack (foo) │
├─────────────────────────────┤
│ m → [ref to "Hello"] │
└─────────────────────────────┘
↓
┌─────────────────────────────┐
│ Heap (Strings) │
├─────────────────────────────┤
│ "Hello" (объект) │
└─────────────────────────────┘
Шаг 2: bar(m) — передаём ЗНАЧЕНИЕ ССЫЛКИ
┌─────────────────────────────┐
│ Stack (bar) │
├─────────────────────────────┤
│ m → [копия ref] = "Hello" │
└─────────────────────────────┘
Шаг 3: m += " World!";
┌─────────────────────────────┐
│ Stack (bar) │
├─────────────────────────────┤
│ m → [новая ref] = "Hello World!"
└─────────────────────────────┘
↓
┌─────────────────────────────┐
│ Heap (Strings) │
├─────────────────────────────┤
│ "Hello" (исходный) │
│ "Hello World!" (новый) │
└─────────────────────────────┘
После выхода из bar(): переменная m в foo() всё ещё указывает на "Hello"
Поддерживающий код
public class StringTest {
public static void main(String[] args) {
String m = "Hello";
System.out.print(m); // Hello
bar(m);
System.out.print(m); // Hello (не изменилось!)
}
static void bar(String m) {
m += " World!"; // Создаёт новый объект, переассоциирует локальную переменную
}
}
// Вывод: HelloHello
Важные концепции
1. String неизменяемость (Immutability)
String str = "Hello";
str += " World"; // Это НЕ изменяет исходный объект
// Вместо этого создаёт НОВЫЙ объект "Hello World"
2. Pass-by-Value в Java
Java передаёт параметры по значению. Но для объектов это значение — ссылка.
void changeString(String s) {
s = "New String"; // Только локальная переменная переассоциируется
// На вызывающий метод это не влияет
}
void changeArray(int[] arr) {
arr[0] = 999; // Это ПОВЛИЯЕТ, так как меняем содержимое объекта
arr = new int[5]; // Это не повлияет на вызывающий метод
}
Вопрос 3: Как изменить код, чтобы получить HelloHello World!?
Вариант 1: Использовать StringBuilder
void foo() {
StringBuilder sb = new StringBuilder("Hello");
System.out.print(sb); // Hello
bar(sb);
System.out.print(sb); // Hello World! (ИЗМЕНИЛОСЬ!)
}
void bar(StringBuilder sb) {
sb.append(" World!"); // Изменяет сам объект, не переассоциирует ссылку
}
// Вывод: HelloHello World!
Вариант 2: Использовать обёртку
class StringWrapper {
String value;
StringWrapper(String value) {
this.value = value;
}
}
void foo() {
StringWrapper wrapper = new StringWrapper("Hello");
System.out.print(wrapper.value); // Hello
bar(wrapper);
System.out.print(wrapper.value); // Hello World!
}
void bar(StringWrapper wrapper) {
wrapper.value += " World!"; // Меняем поле объекта
}
// Вывод: HelloHello World!
Вариант 3: Возвращаемое значение
void foo() {
String m = "Hello";
System.out.print(m); // Hello
m = bar(m); // Присваиваем результат
System.out.print(m); // Hello World!
}
String bar(String m) {
return m + " World!"; // Возвращаем новую строку
}
// Вывод: HelloHello World!
Сравнение подходов
| Подход | Изменяемость | Производительность | Использование |
|---|---|---|---|
| String | Нет | Медленно при конкатенации | Когда не менять |
| StringBuilder | Да | Быстро | При частых изменениях |
| Возвращаемое значение | Нет | Нормально | Чистый подход |
Вывод для интервью
Этот вопрос проверяет:
- Знание неизменяемости String — основной концепции Java
- Понимание pass-by-value — передачи ссылок, а не объектов
- Различие между переассоциацией переменной и изменением объекта
На интервью хорошо объяснить:
- Почему результат
HelloHello - Нарисовать диаграмму памяти (Stack/Heap)
- Предложить решения со StringBuilder и вернуть значение