Проблема, с которой вы сталкиваетесь, заключается не в том, что предикат изменится, но что одна из внешних переменных, на которые ссылается предикат, будет меняться. Поэтому создание копии предиката не помогло бы, потому что оно уже неизменное.
Создание временной переменной, чтобы захватить значение p1
«s исправить эту проблему:
Predicate<String> p1 = str -> str.isEmpty();
final Predicate<String> pTemp = p1;
Predicate<String> p2 = str -> pTemp.test(str);
Причина исправление работает в том, что, когда вы переназначить p1
, старый объект предикат не модифицируются; он заменяется совершенно новым предикатным экземпляром. Старый предикатный объект все еще существует, но при отсутствии живых ссылок он становится пригодным для сбора мусора.
Когда вы добавляете pTemp
, старый предикат будет ссылаться на две переменные, а именно: p1
и pTemp
. На этом этапе повторное присвоение p1
не влияет на pTemp
, поэтому поведение p2
останется неизменным.
Я предполагаю, что это было бы более полезно в цикле, когда вы строите предикат постепенно.
Что клонируется здесь? Ваши предикаты не имеют гражданства, поэтому у вас не должно быть проблем. – teppic
Почему вы не можете повторно использовать старый? – Moira
Ввести другую переменную. Если tou пусть p1 окончательно и ввести p3 = p1, вы можете использовать p1 как неизменяемый, а p3 - как mutable ref. –