Java 为什么我的变量在调用getter时会发生变化?

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

我的项目涉及SpringBoot。因此,在
服务中
我创建了一个方法来检索所有用户可用的默认索引:

@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(...);