В iOS необходимо применить флип-преобразование к текущему графическому контексту для ориентации текста, как показано на рисунке 16- 1. [Отраженное преобразование] включает в себя инвертирование оси Y и перемещение исходной точки в нижнюю часть экрана. В листинге 16-2 показано, как применять такие преобразования в методе
drawRect:
представления iOS. Затем этот метод вызывает тот же методMyDrawText
из листинга 16-1.
Почему? Это кажется совершенно странным. } main () {String myStr = new String (""); changeString (myStr); } Когда main возвращает, значение равно ...
У меня очень неловкий вопрос ...
void changeString(String str){
str = "Hello world":
}
main(){
String myStr = new String("");
changeString(myStr);
}
Когда main
возвращается, значение по-прежнему ""
и не «Привет, мир»
. Почему это так?
Кроме того, как мне заставить это работать? Допустим, я хочу, чтобы моя функция changeString
изменила полученную строку на «Hello world».
Все объяснили, почему это не работает, но никто не объяснил, как заставить это работать. Самый простой вариант - использовать:
String changeString() {
return "Hello world";
}
main() {
String myStr = new String("");
myStr = changeString();
}
Хотя название метода здесь неверное. Если бы вы использовали свою первоначальную идею, вам бы потребовалось что-то вроде:
void changeString(ChangeableString str) {
str.changeTo("Hello world");
}
main() {
ChangeableString myStr = new ChangeableString("");
changeString(myStr);
}
Ваш класс ChangeableString
мог бы быть примерно таким:
class ChangeableString {
String str;
public ChangeableString(String str) {
this.str = str;
}
public void changeTo(String newStr) {
str = newStr;
}
public String toString() {
return str;
}
}
В методе Java все передается по значению. Сюда входят ссылки. Это можно проиллюстрировать этими двумя разными методами:
void doNothing(Thing obj) {
obj = new Something();
}
void doSomething(Thing obj) {
obj.changeMe();
}
Если вы вызываете doNothing (obj)
из main ()
(или где угодно, если на то пошло), obj
не будет изменен в вызываемом объекте, поскольку doNothing
создает новый объект Thing
и назначает эту новую ссылку на obj
в рамках метода .
С другой стороны, в doSomething
вы вызываете obj.changeMe ()
, и это разыменовывает obj
- который был передан по значению - и изменяет Это.
Java использует стратегию по значению для оценки вызовов.
То есть значение копируется в str
, поэтому, если вы назначите str
, это не изменит исходное значение.
Если изменение вашей String
происходит очень часто, вы также можете назначить StringBuffer
или StringBuilder
своей переменной и изменить его содержимое и преобразовывать его в String
только тогда, когда это необходимо.
Немного расширив отличный ответ NullUserException , вот более общее решение:
public class Changeable<T> {
T value;
public Changeable(T value) {
this.value = value;
}
public String toString() {
return value.toString();
}
public boolean equals(Object other) {
if (other instanceof Changeable) {
return value.equals(((Changeable)other).value);
} else {
return value.equals(other);
}
}
public int hashCode() {
return value.hashCode();
}
}
Исходный код Юры можно переписать как:
void changeString(Changeable<String> str){
str.value = "Hello world":
}
void main() {
Changeable<String> myStr = new Changeable<String>("");
changeString(myStr);
}
И, просто для удовольствия, вот он в Scala :
class Changeable[T](var self: T) extends Proxy;
object Application {
def changeString(str: Changeable[String]): Unit = {
str.self = "Hello world";
}
def main(): Unit = {
val myStr = new Changeable("");
changeString(myStr);
}
}
Поскольку ссылка myStr
передается по значению в функцию changeString
, и изменение не отражается обратно в вызывающую функцию.
P.S: Я не Java-парень.