изменить значения аргумента функции? - PullRequest
6 голосов
/ 10 апреля 2011

Это может показаться глупым вопросом, но действительно ли эта функция повлияет на переменную bool (есть более широкий контекст того, как я собираюсь использовать это, но в этом я в основном не уверен)?(Я спрашиваю конкретно о Java)

void truifier (boolean bool) {
    if (bool == false) {
        bool = true;
    }
}

Ответы [ 7 ]

16 голосов
/ 10 апреля 2011

Рассмотрим немного другой пример:

public class Test {

    public static void main(String[] args) {
        boolean in = false;
        truifier(in);
        System.out.println("in is " + in);
    }

    public static void truifier (boolean bool) {
        if (bool == false) {
            bool = true;
        }
        System.out.println("bool is " + bool);
    }
}

Результат выполнения этой программы будет:

bool is true
in is false

Переменная bool будет изменена на true, но как только метод truifier вернется, эта переменная аргумента исчезнет (это то, что люди имеют в виду, когда говорят, что она "выходит за рамки"). Однако переменная in, переданная методу truifier, остается без изменений.

7 голосов
/ 19 мая 2016

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

class Foo {
        boolean is = false;
}
class Test
{

    static void trufier(Foo b)
    {
        b.is = true;
    }
    public static void main (String[] args)
    {
        // your code goes here
        Foo bar = new Foo();
        trufier(bar);
        System.out.println(bar.is);
    }
}

Если, однако, вы используете не логическое значение, а объект, параметр может изменить объект. // ВЫВОДЫ ЭТОГО КОДА ИСТИНА

3 голосов
/ 10 апреля 2011
void truifier (boolean bool) {
    if (bool == false) {
        bool = true;
    }
}

void demo () {
    boolean test = false;
    truifier (test); 
    // test is still false
    System.out.println (test);
}

Вы знаете, что можете вызывать функцию с буквальной константой - что здесь нужно изменить?

void demo2 () {
    truifier (false); 
}

Или с конечной локальной переменной

void demo2 () {
    final boolean b = false;
    truifier (b); 
}

Или с атрибутами из класса:

class X {
    private boolean secret = false; 

    void demo3 () {
        truifier (secret); 
    }
}

Во всех этих вызовах truifier получает локальную копию ссылки на рассматриваемый объект.

boolean b = false;
// b -> false  

b является ссылкой на объект «ложь» - или в данном случае на примитивное значение.

boolean c = b; 
// c -> false, not: c-> b -> false
c = true; 
// c -> true

с изменен, но не б. c не псевдоним для b, а копия ссылки, и теперь копия ссылается на true. Здесь есть только 2 реальных объекта (примитива): true и false.

При вызове метода копия ссылки создается и передается, и изменения в этой ссылке влияют только на это. Однако глубокого копирования нет. С классом, для которого вы меняете атрибут, этот атрибут будет изменен снаружи, но вы не можете заменить сам класс. Или Массивы: Вы можете изменить содержимое массива (ссылка на копию указывает на тот же массив), но не сам массив (например, размер). Хорошо - вы можете изменить его в методе, но внешняя ссылка независима и не изменилась.

k = [a, b, c, d]
l = k; 
l [2] = z;
// l=k=[a, b, z, d]
l = [p, q, r]
// k = [a, b, z, d]
1 голос
/ 10 апреля 2011

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

Также ваш пример можно переписать так:

if (!bool) {
    bool = true;
}
1 голос
/ 10 апреля 2011

Да, только в объеме функции.

0 голосов
/ 09 июня 2019

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

Во-первых, вы включаете логическую переменную с классом

class MyBoolean {
private boolean b;
}

Во-вторых, вы добавляете подходящий конструктор:

class MyBoolean {
private boolean b;
public MyBoolean(boolean b) {
this.b = b;
}

Затем вы добавляете 2 метода: получить и изменить;метод get возвращает текущее значение логической переменной, а метод alter переключает ее значение.

class MyBool {
        private boolean b;
        public MyBool(final boolean b) { this.b = b; }
        public boolean getValue() { return b; }
        public void alter() { 
            if(b == true) {
                b = false;
                return;
            }
            b = true;
        }

    @Override
    public String toString() {
        return b+"";
    }
}

Итак, вместо определения логической переменной вы определяете объект MyBoolean.

ТогдаВы передаете этот объект своей функции «правдоподобия», с небольшими изменениями:

public static void truifier(MyBoolean b) {
b.alter();
} 

И, наконец, значение булевой переменной внутри объекта «b» теперь изменяется.

0 голосов
/ 10 апреля 2011

Похоже, что первоначальный вопрос касается «звонка по ссылке» или его отсутствия.

Чтобы сделать это более понятным, рассмотрим:

 void caller() {
    boolean blooean = false;
    truifier(blooean);
    System.err.println(blooean);
 }

Это выведет «false».

Аналогичный вызов в конце trueifier выведет «true».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...