Java 为什么我的变量在调用getter时会发生变化?
我的项目涉及SpringBoot。因此,在Java 为什么我的变量在调用getter时会发生变化?,java,spring-boot,Java,Spring Boot,我的项目涉及SpringBoot。因此,在服务中我创建了一个方法来检索所有用户可用的默认索引: @Service public class UserService { @Autowired private UserRepository userRepository; @Autowired private IndexRepository indexRepository; /** * Read from application.properties * * We only store
服务中
我创建了一个方法来检索所有用户可用的默认索引:
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private IndexRepository indexRepository;
/**
* Read from application.properties
*
* We only store the index ids in the application.properties
*/
@Value("${default.allowed.ids}")
private String defaultAllowedIds;
// I've also tried and removed the static with the same behaviour
private static HashSet<Index> listOfDefaultAllowedIndex = null;
public User findByUsername(String username) {
return userRepository.findByUsername(username);
}
public User findByResetToken(String resetToken) {
return userRepository.findByResetToken(resetToken);
}
/**
* Saves the user in the database and encrypts the password with bcrypt.
*
* @param user
*/
public void save(User user) {
// Code to save a new user
}
public void update(User user) {
// COde to update the user
}
/**
* List the default index allowed by default to all users
*
* @return the listOfDefaultAllowedIndex
*/
private HashSet<IndexSetup> getListOfDefaultAllowedIndex() {
System.err.println("TEST : DEFAULT LIST CONTAINS " + (listOfDefaultAllowedIndex != null ?
listOfDefaultAllowedIndex.size() + " index" : "NULL"));
// This is null at the beginning then it grows
System.err.println("TEST : THE DEFAULT STRING IS " + defaultAllowedIndexIds);
// This is always an empty string
if (listOfDefaultAllowedIndex == null) {
// 1) Gets the ids from the property
HashSet<String> defaultIds = new HashSet(Stream.of(
defaultAllowedIndexIds.split(
SEMI_COLON_SEPARATOR)).collect(Collectors.toSet()));
System.err.println("TEST : DEFAULT IDS : " + defaultIds); // THis is empty
// 2) Converts them into list of Index object
listOfDefaultAllowedIndex = new HashSet(StreamSupport
.stream(indexRepository.findAll().spliterator(),
false)
.filter(idx -> defaultIds.contains(Integer.toString(
idx.getId())))
.collect(Collectors.toSet()));
System.err.println("TEST : CONVERTED INDEX : ");
listOfDefaultAllowedIndex.stream().forEach(
idx -> System.err.println(idx.getName() + " (" + idx.getId() + ")")); // THis is empty
}
System.err.println("TEST : READING FROM CACHE (FROM THREAD " + Thread.currentThread().getName() + ") FOR THE DEFAULT IDS : ");
listOfDefaultAllowedIndex.stream().forEach(
idx -> System.err.println(idx.getName() + " (" + idx.getId() + ")"));
// THis should be empty but is growing
return listOfDefaultAllowedIndex;
}
这实际上回答了我的问题
为了解决这个问题,我必须通过将集合
包装到集合中,返回一个不可变的集合
。哇,我完全忘了
感谢任何帮助最可能的原因:
您正在将内部哈希集泄漏给getter的调用者
因此,如果调用方修改它作为getter返回值得到的HashSet
,这个更改将反映在内部字段值中,因为它是非常相同的HashSet
对象
要检查:从getter返回一个集合.unmodifiableSet(listOfDefaultAllowedIndex)
(并将返回类型调整为集合
,而不是哈希集
)。然后,任何试图更改集的调用方都将得到异常,而不是修改任何内容。然后,您可以决定如何继续:例如,让此来电者制作一份副本,始终返回字段哈希集的副本谢谢@ralf kleberhoff您搞定了!我忘了只返回了对对象的引用,而不是副本!
HashSet<Index> allowedIndexes = this.getListOfDefaultAllowedIndex();
//...
allowedIndexes.addAll(...);