номер
В Java каждая переменная объекта является ссылкой. Объекты не могут быть переданы по значению, только примитивы могут (и всегда). Ну, это немного вводит в заблуждение. ссылка передается по значению, но вы можете думать, что все является ссылкой, но не в смысле C ++.
Возможно, проще всего использовать пример.
SomeObject foo;
public void doSomething(SomeObject bar) {
bar.whatever();
bar = new SomeObject();
bar.someOtherMethod();
}
public void doStuff() {
foo = new SomeObject();
doSomething(foo);
}
Итак, foo
является ссылкой на экземпляр SomeObject
. Когда вызывается doSomething
, значение этой ссылки копируется в bar
, поэтому теперь foo
и bar
являются ссылками на один и тот же SomeObject
.
Строка bar.whatever()
вызывает whatever
для того же объекта, к которому относится foo
.
bar = new SomeObject()
означает, что foo
и bar
теперь относятся к различным SomeObject
экземплярам, поэтому someOtherMethod
это не , вызываемый для объекта, foo
относится к.
Это полностью отличается от C ++, где
void doSomething(SomeObject& bar) {
bar = whatever;
}
имеет совершенно другое значение. Вы действительно никогда не должны думать о Java в терминах C ++.
Что касается вашего примера, String
s являются неизменяемыми в Java, поэтому не имеет значения, даже если объекты могут быть переданы по значению.
Что касается вашего второго примера, если вы хотите вернуть объект, который вызывающая сторона не может использовать для загрязнения вашего внутреннего состояния, тогда да, вам нужно иметь конструктор копирования (или что-то эквивалентное).
Например:
class ClassWithInternalList {
private List<String> reallyImportantData;
public List<String> getImmutableViewOfData() {
// Take advantage of the java.util.Collections tool for making a List immutable.
return Collections.unmodifiableList(reallyImportantData);
}
public List<String> getSafeCopyOfData() {
// Return a copy that the caller can modify without changing reallyImportantData.
return new ArrayList<String>(reallyImportantData);
}
public List<String> justGetTheData() {
// Return a reference to reallyImportantData that the caller can modify at will.
return reallyImportantData;
}
}
Вы можете выбрать соответствующий тип возвращаемого значения (обычная ссылка, неизменяемый вид или копия) в зависимости от ситуации. Любой или все три варианта могут быть подходящими в зависимости от того, что именно вы делаете.
java.util.Collections
позволяет легко получить неизменяемое представление Collection
, но для пользовательских классов вам нужно сделать свою собственную неизменяемость.
Помните, что вам нужно делать это только в случае проблемы с изменчивостью. Ваш пример MyCustomObject
по-прежнему неизменен (поскольку вызывающий не может изменить состояние в возвращенном экземпляре MyCustomObject
), поэтому вопрос по-прежнему спорный.