StackOverflowError棧溢出錯誤

一般棧溢出是因爲在某個class A中調用了class A.所以就陷入了死循環. 
問題的基本原理如下:
Class A{
  public A(){
     a= new A();
  }
}


 
你說這能不造成java.lang.StackOverflowError嘛,所以寫代碼我們要避免寫這樣的代碼,應該將其放入到 方法體中(自己的Constructer除外) 或者是放入到 Static 中,以上的代碼用JVM的指令,其實如下:
0:   aload_0
1:   invokespecial  #1; //Method  java/lang/object .<init>
4:   aload_0 
5:   new  #2; //class A
8:   dup
9:   invokespecial  #3; //Method  java/lang/object .<init>
12: putfield    #4; //Field a:LA;
15: return
 

在這裏  constructer 中是調用 init , 而 static 是調用 cinit , 固我們如果將自己的對象放入到 static 中是不會找成循環的, 而如果將自己本身放到 constructer 中他就會不段的調用 init , 所以才發生了上面的java.lang.StackOverflowError 溢出錯誤.

當然,一般人不會犯這麼低級的錯誤.
下面我就拿我的項目遇到的問題來說一下.
我的問題是由於在某個類中與另一個類有一對多關係.導致陷入了死循環.
代碼如下:

一對多類:User.java(一個User對應多個letter)
public class User {	
	private List<Letter> lettersForFromId;
	private List<Letter> lettersForToId;
	public User() {}
	@OneToMany(fetch = FetchType.LAZY, mappedBy = "userByFromId")
	public List<Letter> getLettersForFromId() {
		return this.lettersForFromId;
	}
	public void setLettersForFromId(List<Letter> lettersForFromId) {
		this.lettersForFromId = lettersForFromId;
	}
	@OneToMany(fetch = FetchType.LAZY, mappedBy = "userByToId")
	public List<Letter> getLettersForToId() {
		return this.lettersForToId;
	}
	public void setLettersForToId(List<Letter> lettersForToId) {
		this.lettersForToId = lettersForToId;
	}
}

多對一類:Letter.java
public class Letter extends IdEntity {

	private static final long serialVersionUID = -2305610965537901463L;
	private User userByToId;
	private User userByFromId;
	public Letter() {
	}
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "to_id", nullable = false)
	public User getUserByToId() {
		return this.userByToId;
	}

	public void setUserByToId(User userByToId) {
		this.userByToId = userByToId;
	}

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "from_id", nullable = false)
	public User getUserByFromId() {
		return this.userByFromId;
	}

	public void setUserByFromId(User userByFromId) {
		this.userByFromId = userByFromId;
	}

看到上面例子,仔細對比一下,不難發現. 導致我的User與Letter無限遞歸,導致陷入死循環,導致棧溢出.
解決方法:
在Letter中所有調用User處加上@JsonIgnore,如:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "to_id", nullable = false)
@JsonIgnore
public User getUserByToId() {
	return this.userByToId;
}



Ps:因爲我在數據庫中請求是以json格式的. 
@JsonIgnore的意思是不再向下便利.
到此,問題解決了. 
這裏主要是記錄一下學習筆記,希望能順便幫助一下遇到相同問題的朋友. 
具體問題還是要具體分析.

發佈了37 篇原創文章 · 獲贊 41 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章