我将通过给您一个描述性示例来解释自己。假设我正在编写一个非常简单的云存储模拟,一个简单的终端程序。我有两个主要类,用户和文件,编码如下:
class User {
Set<File> sharedFiles;
void shareFile(File f){
sharedFiles.add(f);
f.shareWith(this);
}
}
class File {
Set<User> sharedUsers;
void shareWith(User u){
sharedUsers.add(u);
u.shareFile(this);
}
}
我假装有权访问已共享给用户的文件以及已共享文件的用户,因此我对列表进行了编码 sharedFiles
和sharedUsers
.
那么,我会:
main(){
User u = new User();
File f = new File();
u.shareFile(f); // or f.shareWith(u), doesn't matter
}
我知道这是一个非常明显的无限循环情况。事实上,这段代码会导致 Exception in thread "main" java.lang.StackOverflowError
。两种方法都会无限期地互相调用。
那么,在您看来,这个问题的理想解决方案以及这两个类的良好设计是什么?
最佳答案
您可以在调用 shareWith
方法之前添加检查一个类的对象是否已持有对另一类的对象的引用:
class User {
Set<File> sharedFiles;
boolean hasFile (File f) {
return sharedFiles.contains(f);
}
void shareFile(File f){
sharedFiles.add(f);
if (!f.hasUser(this))
f.shareWith(this);
}
}
class File {
Set<User> sharedUsers;
boolean hasUser (User u) {
return sharedUsers.contains(u);
}
void shareWith(User u){
sharedUsers.add(u);
if (!u.hasFile(this))
u.shareFile(this);
}
}
编辑:当然,此代码缺少 sharedUsers
和 sharedFiles
集的初始化,但我假设您在实际代码中具有该初始化。
关于java - 这个设计有什么问题导致无限循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46218512/