常見的 Java 錯誤及避免方法之第四集(每集10個錯誤後續持續發佈)

31.“Could Not Create Java Virtual Machine”

當我們嘗試調用帶有錯誤參數的Java代碼時,通常會產生此Java錯誤消息(@ghacksnews):

Error: Could not create the Java Virtual MachineError: A fatal exception has occurred. Program will exit.

這通常是由於代碼中的聲明存在錯誤或爲其分配適當的內存而引起的。

閱讀關於如何修復Java軟件錯誤“Could Not Create Java Virtual Machine”的討論。(@StackOverflow)

32.“class file contains wrong class”

當Java代碼嘗試在錯誤的目錄中尋找類文件時,就會出現“class file contains wrong class”的問題,導致類似於以下內容的錯誤消息:

MyTest.java:10: cannot access MyStruct 
bad class file: D:\Java\test\MyStruct.java file does not contain class MyStruct Please remove or make sure it appears in the correct subdirectory of the classpath. 
MyStruct ms = new MyStruct();

要修復此錯誤,以下這些提示可以提供幫助:

  • 確保源文件的名稱和類的名稱匹配——包括大小寫。
  • 檢查軟件包語句是否正確或是否缺失。
  • 確保源文件位於正確的目錄中。

閱讀此關於如何修復“class file contains wrong class”錯誤的討論。(@StackOverflow)

33.“ClassCastException”

“ClassCastException”消息指示了Java代碼正在嘗試將對象轉換爲錯誤的類。在來自Java Concept of Day的這個例子中,運行以下程序:

package com;class A{    int i = 10;
}class B extends A{    int j = 20;
}class C extends B{    int k = 30;
}public class ClassCastExceptionDemo{    public static void main(String[] args)
    {
        A a = new B();   //B type is auto up casted to A type
        B b = (B) a;     //A type is explicitly down casted to B type.
        C c = (C) b;    //Here, you will get class cast exception
        System.out.println(c.k);
    }
}

導致以下錯誤:

Exception in thread “main” java.lang.ClassCastException: com.B cannot be cast to com.Cat com.ClassCastExceptionDemo.main(ClassCastExceptionDemo.java:23)

Java代碼將創建一個類和子類的層次結構。爲了避免“ClassCastException”錯誤,請確保新類型屬於正確的類或其父類之一。如果使用泛型,則編譯代碼時可能會捕獲這些錯誤。

閱讀此教程以瞭解如何修復“ClassCastException”的Java軟件錯誤。(@java_concept)

34.“ClassFormatError”

“ClassFormatError”消息指示鏈接錯誤,並且發生在類文件不能被讀取或解釋爲類文件的時候。

Caused by: java.lang.ClassFormatError: Absent Code attribute in method that is        not native or abstract in class file javax/persistence/GenerationTypeat java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$000(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)

有若干原因會導致“ClassFormatError”錯誤:

  • 類文件以ASCII模式而不是二進制模式上傳。
  • Web服務器必須以二進制而不是ASCII格式發送類文件。
  • 可能會有一個類路徑錯誤,阻止了代碼找到類文件。
  • 如果類被加載兩次,那麼第二次將導致拋出異常。
  • 正在使用舊版本的Java運行時。

閱讀此關於導致Java“ClassFormatError”錯誤的原因的討論。(@StackOverflow)

35.“ClassNotFoundException”

“ClassNotFoundException”僅在運行時發生——意味着在編譯期間有一個類在運行時缺失了。這是一個鏈接錯誤。

很像“NoClassDefFoundError”,在以下情況下會出現這個問題:

  • 該文件不在正確的目錄中。
  • 類的名稱必須與文件的名稱相同(不包括文件擴展名)。 名稱區分大小寫。

閱讀此關於導致“ClassNotFoundException”原因的更多案例的討論。(@StackOverflow)。

36.“ExceptionInInitializerError”

此Java問題發生在靜態初始化出錯的時候(@GitHub)。 當Java代碼稍後使用該類時,將發生“NoClassDefFoundError”錯誤。

java.lang.ExceptionInInitializerError
  at org.eclipse.mat.hprof.HprofIndexBuilder.fill(HprofIndexBuilder.java:54)
  at org.eclipse.mat.parser.internal.SnapshotFactory.parse(SnapshotFactory.java:193)
  at org.eclipse.mat.parser.internal.SnapshotFactory.openSnapshot(SnapshotFactory.java:106)
  at com.squareup.leakcanary.HeapAnalyzer.openSnapshot(HeapAnalyzer.java:134)
  at com.squareup.leakcanary.HeapAnalyzer.checkForLeak(HeapAnalyzer.java:87)
  at com.squareup.leakcanary.internal.HeapAnalyzerService.onHandleIntent(HeapAnalyzerService.java:56)
  at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:145)  at android.os.HandlerThread.run(HandlerThread.java:61)
Caused by: java.lang.NullPointerException: in == null
  at java.util.Properties.load(Properties.java:246)  at org.eclipse.mat.util.MessageUtil.(MessageUtil.java:28)  at org.eclipse.mat.util.MessageUtil.(MessageUtil.java:13)
  ... 10 more

修復此錯誤我們需要更多的信息。在代碼中使用getCause()可以返回導致錯誤的異常。

閱讀此關於如何追蹤ExceptionInInitializerError原因的討論。(@StackOverflow)

37.“IllegalBlockSizeException”

當長度消息不是8字節的倍數時,那麼在解密期間就會拋出“IllegalBlockSizeException”異常。以下是一個出自ProgramCreek.com的示例(@ProgramCreek):

@Overrideprotected byte[] engineWrap(Key key) throws IllegalBlockSizeException, InvalidKeyException {    try {        byte[] encoded = key.getEncoded();        return engineDoFinal(encoded, 0, encoded.length);
    } catch (BadPaddingException e) {
        IllegalBlockSizeException newE = new IllegalBlockSizeException();
        newE.initCause(e);        throw newE;
    }
}

“IllegalBlockSizeException”可能是由以下原因引起的:

  • 使用不同的加密和解密算法選項。
  • 要解密的消息可能在傳輸中被截斷或亂碼。

閱讀關於如何防止IllegalBlockSizeException Java軟件錯誤消息的討論。(@StackOverflow)

38.“BadPaddingException”

當使用填充來創建一個消息而不是8字節的倍數時,那麼在解密期間可能會出現“BadPaddingException”異常。這是出自Stack Overflow的一個例子(@StackOverflow):

javax.crypto.BadPaddingException: Given final block not properly paddedat com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)at javax.crypto.Cipher.doFinal(DashoA13*..)

加密數據是二進制的,所以不要嘗試將其存儲在字符串或在加密期間沒有被正確填充的數據中。

閱讀關於如何防止BadPaddingException的討論。(@StackOverflow)

39.“IncompatibleClassChangeError”

“IncompatibleClassChangeError”是LinkageError的一種形式,如果一個在基類在編譯子類之後發生變化,那麼就會出現此異常。下面這個例子來自於How to Do in Java(@HowToDoInJava):

Exception in thread "main" java.lang.IncompatibleClassChangeError: Implementing classat java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$000(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
at net.sf.cglib.core.DebuggingClassWriter.toByteArray(DebuggingClassWriter.java:73)
at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:26)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
at net.sf.cglib.core.KeyFactory$Generator.create(KeyFactory.java:144)
at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:116)
at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:108)
at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:104)
at net.sf.cglib.proxy.Enhancer.(Enhancer.java:69)

出現“IncompatibleClassChangeError”有可能的原因是:

  • 忘記了主方法的靜態。
  • 非法使用了legal類。
  • 類被改變了,並且存在通過舊的簽名從另一個類到這個類的引用。嘗試刪除所有類文件並重新編譯所有內容。

嘗試解決“IncompatibleClassChangeError”的這些步驟(@javacodegeeks)

40.“FileNotFoundException”

當具有指定路徑名的文件不存在時,將拋出此Java軟件錯誤消息。

@Override public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {    if (uri.toString().startsWith(FILE_PROVIDER_PREFIX)) {        int m = ParcelFileDescriptor.MODE_READ_ONLY;        if (mode.equalsIgnoreCase("rw")) m = ParcelFileDescriptor.MODE_READ_WRITE;
        File f = new File(uri.getPath());
        ParcelFileDescriptor pfd = ParcelFileDescriptor.open(f, m);        return pfd;
    } else {        throw new FileNotFoundException("Unsupported uri: " + uri.toString());
    }
}

除了沒有指定路徑名的文件之外,這可能意味着現有文件無法訪問。

閱讀關於爲什麼會拋出“FileNotFoundException”的討論。(@StackOverflow)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章