作者:我病态见不得你跟别人恩爱 | 来源:互联网 | 2024-12-03 18:39
在开发Java应用程序时,经常需要自定义类的toString方法来方便调试和日志记录。然而,不当的实现可能导致严重的性能问题,甚至程序崩溃。例如,在我的项目中有两个类:User和Role,它们之间存在多对一的关系。
在User类中,我重写了toString方法以提供详细的用户信息输出:
@Override
public String toString() {
return "User [userId=" + this.userId + ", profileName=" + this.profileName+ ", firstName=" + this.firstName + ", lastName=" + this.lastName+ ", email=" + this.email + ", socialEmail=" + this.socialEmail+ ", accountEnabled=" + this.accountEnabled + ", accountNOnExpired="+ this.accountNonExpired + ", accountNOnLocked=" + this.accountNonLocked+ ", country=" + this.country + ", role=" + this.role + "]";
}
同样地,在Role类中也实现了toString方法:
@Override
public String toString() {
return "Role [roleId=" + roleId + ", users=" + users + ", role=" + role
+ "]";
}
通过Hibernate框架从数据库查询用户详细信息时,遇到了一个问题。具体代码如下:
@SuppressWarnings("unchecked")
public User getUser(String name){
List userList = new ArrayList();
Query query = sessionFactory.getCurrentSession().createQuery("from User u where u.profileName = :name or u.socialEmail = :name");
query.setParameter("name", name);
userList = query.list();
if (userList.size() > 0)
return userList.get(0);
else
return null;
}
当执行到userList = query.list();
这一行时,程序抛出了StackOverflowError异常,指出问题在于toString方法的调用。
异常堆栈信息如下:
java.lang.StackOverflowError
at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:113)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:415)
at java.lang.StringBuilder.append(StringBuilder.java:132)
at java.lang.StringBuilder.(StringBuilder.java:110)
at com.myapp.model.User.toString(User.java:189)
at java.lang.String.valueOf(String.java:2902)
at java.lang.StringBuilder.append(StringBuilder.java:128)
at java.util.AbstractCollection.toString(AbstractCollection.java:450)
at org.hibernate.collection.PersistentSet.toString(PersistentSet.java:310)
at java.lang.String.valueOf(String.java:2902)
at java.lang.StringBuilder.append(StringBuilder.java:128)
at com.myapp.model.Role.toString(Role.java:67)
进一步检查发现,异常发生在User类的toString方法的起始位置:at com.myapp.model.User.toString(User.java:189)
。
原因分析:在User类的toString方法中引用了Role对象,而在Role类的toString方法中又引用了User对象。这种双向引用导致了无限递归,即当尝试打印某个角色的所有用户时,每个用户的toString方法又会试图打印其关联的角色,从而形成循环。
解决方案:为了避免这种循环引用导致的堆栈溢出错误,可以在toString方法中添加逻辑判断,仅在必要时打印关联对象的信息。例如,可以通过设置标志位或使用其他策略来避免无限递归,确保每次调用toString时都能正确终止。