Есть ли способ гарантировать, что реальный объект ссылки не имеет побочного эффекта для вызывающей функции? - PullRequest
0 голосов
/ 17 января 2020

Я студент, который недавно изучает JAVA.
Я подхожу к этому языку, основываясь на своем опыте C ++.

Итак, мне потребовалось почти четыре дня, чтобы понять разрыв между c ++ и java с точки зрения вызова по значению или ссылки.

Java является вызовом по значению, потому что вызывающая функция передает переменную ссылочного типа самой вызываемой стороне.

Когда я понял вышеприведенное предложение, у меня неожиданно возник вопрос:
Мой вопрос таков:

Я узнал, что один из вызовов по значению преимущества без побочных эффектов .

В JAVA гарантируется, что переменная ссылочного типа сама по себе не имеет побочного эффекта.
Но реальный объект, на который ссылается ссылочная переменная, может иметь побочный эффект
after возвращает функцию вызова.

Так есть ли способ гарантировать, что ссылка на объект в памяти кучи также не имеет побочного эффекта для функции вызывающей стороны?

(И если я неправильно понял механизм JAVA, пожалуйста, скажите мне)

=========================== =========
Добавить пример

class Person{
    String  name;
    int     age;
    Person(String name, int age){
        this.name = name;
        this.age =age;
    }

}


public static void foo(){
    Person p = new Person("haha", 17);

    System.out.println(p.name); // haba

    boo(p);


    System.out.println(p.name); // hoho, but foo() wants original value "haha"

}

public static void boo(Person p){
    p.name = "hoho";

}

Я хочу, чтобы функция boo () не изменяла переменную-член (здесь p.name) экземпляра p.

Ответы [ 2 ]

0 голосов
/ 17 января 2020

Ниже приведен небольшой пример того, как вы можете передавать копии объектов, гарантируя, что исходный объект не изменяется.

Когда я использую конструктор копирования, внутреннее состояние исходного объекта сохраняется, но когда я просто заявляю TestRef otherRef = testRef;, копируется только ссылка, так что, если новый объект изменяется, то и оригинал изменяется.

Обратите внимание, что в этом случае я действительно копирую ссылку на строку, поскольку строки являются неизменяемыми классами в java.

public class Main {

    public static class TestRef {
        public String a;
        public int b;

        //Copy constructor
        public TestRef(TestRef other) {
            this(other.a, other.b);
        }

        public TestRef(String a, int b) {
            this.a = a;
            this.b = b;
        }

    }

    public static void main(String[] args) throws IOException, TransformerException {

        TestRef testRef = new TestRef("TestRef", 1);
        //Using copyConstructor to make deep copy of object
        System.out.println(testRef.a);
        TestRef deepCopy = new TestRef(testRef);
        modifyClass(deepCopy);
        System.out.println(testRef.a);
        //Shallow copy
        TestRef otherRef = testRef;
        modifyClass(otherRef);
        System.out.println(testRef.a);      
    }

    public static void modifyClass(TestRef testRef) {
        testRef.a = "newString";
        testRef.b++;
    }
}

ВЫХОД:

TestRef
TestRef
newString
0 голосов
/ 17 января 2020

Вы можете сделать это:

class Person{
    final String name;
    int age;
Person(String name, int age){
        this.name = name;
        this.age =age;
    }
}
...