API 就像是呼叫者與被呼叫者之間簽訂的規定。最常見的 API 濫用形式是由呼叫者這一當事方未能遵守此規定所造成的。例如,如果程式在呼叫 chroot() 後無法呼叫 chdir(),即違反規範如何以安全方式變更使用中根目錄的規定。程式庫濫用的另一個好例子是期待被呼叫者向呼叫者傳回值得信賴的 DNS 資訊。在這種情況下,呼叫者是透過對其行為做出某些假設 (傳回值可用於驗證目的) 來濫用被呼叫者 API。另一方也可能違反呼叫者與被呼叫者間的規定。例如,如果編碼器衍生出子類別 SecureRandom 並傳回一個非隨機值,則違反了規定。
Equals()
的物件上呼叫 Equals()
。Equals()
的類別 (或任何上層類別/介面) 上呼叫 Equals()
,會造成對繼承自 System.Object
的 Equals()
方法的呼叫。Object.Equals()
會比較兩個物件實例來確認物件是否相同,而不是比較物件成員欄位或其他特性。雖然有合法的 Object.Equals()
使用,但是這通常表示程式碼錯誤。
public class AccountGroup
{
private int gid;
public int Gid
{
get { return gid; }
set { gid = value; }
}
}
...
public class CompareGroup
{
public bool compareGroups(AccountGroup group1, AccountGroup group2)
{
return group1.Equals(group2); //Equals() is not implemented in AccountGroup
}
}
equals()
的物件上呼叫 equals()
方法。equals()
的類別 (或任何上層類別/介面) 上呼叫 equals()
,會造成對繼承自 java.lang.Object
的 equals()
方法的呼叫。Object.equals()
會比較兩個物件實例來確認物件是否相同,而不是比較物件成員欄位或其他特性。雖然有合法的 Object.equals()
使用,但是這通常表示程式碼錯誤。
public class AccountGroup
{
private int gid;
public int getGid()
{
return gid;
}
public void setGid(int newGid)
{
gid = newGid;
}
}
...
public class CompareGroup
{
public boolean compareGroups(AccountGroup group1, AccountGroup group2)
{
return group1.equals(group2); //equals() is not implemented in AccountGroup
}
}
finalize()
方法應該呼叫 super.finalize()
。finalize()
方法中呼叫 super.finalize()
方法是一種非常好的做法 [1]。super.finalize()
。
protected void finalize() {
discardNative();
}
private void writeObject(java.io.ObjectOutputStream out) throws IOException;
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;
private void readObjectNoData() throws ObjectStreamException;
getOutputStream
之後呼叫 getWriter()
或 (反之亦然) 也是錯誤的。HttpServletRequest
、重新導向 HttpServletResponse
或排清 Servlet 的輸出串流緩衝區等,都會造成相關的串流交付。任何後續的緩衝區重設或串流交付時 (例如其他排清或重新導向),將造成 IllegalStateException
。ServletOutputStream
或 PrintWriter
(但不是兩者同時),將資料重新寫入回應串流。呼叫 getOutputStream()
之後呼叫 getWriter()
(反之亦然) 也會造成 IllegalStateException
。IllegalStateException
可防止回應處理常式執行完成,以有效撤銷回應。這樣可能會造成伺服器不穩定,而這是錯誤執行的 Servlet 徵兆。範例 2:相反地,以下程式碼嘗試在發送要求之後寫入和排清
public class RedirectServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
...
OutputStream out = res.getOutputStream();
...
// flushes, and thereby commits, the output stream
out.flush();
out.close(); // redirecting the response causes an IllegalStateException
res.sendRedirect("http://www.acme.com");
}
}
PrintWriter
的緩衝區。
public class FlushServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
...
// forwards the request, implicitly committing the stream
getServletConfig().getServletContext().getRequestDispatcher("/jsp/boom.jsp").forward(req, res);
...
// IllegalStateException; cannot redirect after forwarding
res.sendRedirect("http://www.acme.com/jsp/boomboom.jsp");
PrintWriter out = res.getWriter();
// writing to an already-committed stream will not cause an exception,
// but will not apply these changes to the final output, either
out.print("Writing here does nothing");
// IllegalStateException; cannot flush a response's buffer after forwarding the request
out.flush();
out.close();
}
}
Content-Length
表頭設為負數。Content-Length
表頭即表示開發人員想要0
或者Content-Length
。
URL url = 新 URL(「http://www.example.com」);
HttpURLConnection huc = (HttpURLConnection)url.openConnection();
huc.setRequestProperty("Content-Length", "-1000");
Content-Length
表頭設為負數。Content-Length
表頭即表示開發人員想要0
或者Content-Length
表頭錯設為負數:
xhr.setRequestHeader("Content-Length", "-1000");
ToString()
在陣列上受到呼叫。ToString()
表示開發人員有意將陣列內容做為字串回傳。不過,在陣列上直接呼叫 ToString()
,將會回傳包含陣列類型的字串值。System.String[]
。
String[] stringArray = { "element 1", "element 2", "element 3", "element 4" };
System.Diagnostics.Debug.WriteLine(stringArray.ToString());
toString()
在陣列上受到呼叫。toString()
表示開發人員有意將陣列內容做為字串回傳。不過,在陣列上直接呼叫 toString()
,將會回傳記憶體中包含陣列類型和雜湊碼的字串值。[Ljava.lang.String;@1232121
。
String[] strList = new String[5];
...
System.out.println(strList);