Java文件編譯出現 “編碼 GBK 的不可映射字符”


俗話說,溫故而知新。本打算用dos回憶一下基礎知識,沒想到把自己絆倒了。

用Dos,當然就要回歸原始,用記事本啦。下面用一個小練習,演示我遇到的絆腳石。之后,解決了簡直笑死。

報錯:

Java文件編譯出現“編碼 GBK 的不可映射字符”

(下圖不是我的,我的忘記截圖了。但是為了方便演示,我在網上找了相同問題的圖片,之后的圖都是我自己截我自己的了)

在notepad++里面的代碼是在Myeclipse里面粘貼過來的,運行過的。

代碼實例:

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Demo6 {

    /*
     * @param args
     * 
     * @在記事本中驗證 測試好用
     * 
     * @author 周周
     * 
     * @version 1.1
     */
    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub

        // 定義一個可以存放四只狗的對象數組
        DogNew dogs[] = new DogNew[4];

        // 從控制台輸入各個狗的信息
        InputStreamReader isr = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(isr);

        for (int i = 0; i < 4; i++) {
            dogs[i] = new DogNew();

            System.out.println("請輸入第" + (i + 1) + "只狗的名字");

            // 從控制台讀取狗名

            String name = br.readLine();

            // 將名字賦給對象
            dogs[i].setName(name);

            System.out.println("請輸入第" + (i + 1) + "只狗的體重");
            String s_weight = br.readLine();
            // 只要編譯器看到readLine,程序就會停在那里等你輸入,你不輸入它不往下進行
            // 但是,readLine讀進來之后總是一個字符串,依照要求,需要自己強轉一下
            float weight = Float.parseFloat(s_weight);
            // 將名字賦給對象
            dogs[i].setWeight(weight);

        }
        // 計算總體重
        float allWeight = 0;
        for (int i = 0; i < 4; i++) {
            allWeight += dogs[i].getWeight();// getWeight()指取出對應狗的體重。把它累計給allWeight這個變量
        }
        // 計算平均體重
        float avgWeight = allWeight / dogs.length;// 這里沒有除以4.而是直接計算出對象數組的大小了

        System.out.println("總體重:" + allWeight + "   平均體重:" + avgWeight);

        // 找出體重最大的狗
        // 假設 第一只狗體重最大
        float maxWeight = dogs[0].getWeight();
        int maxIndex = 0;
        // 按順序和后面的狗比較
        for (int i = 1; i < dogs.length; i++) {
            if (maxWeight < dogs[i].getWeight()) {
                // 修改
                maxWeight = dogs[i].getWeight();
                maxIndex = i;
            }

        }
        System.out.println("體重最大的狗是第" + (maxIndex + 1) + "     體重是"
                + dogs[maxIndex].getWeight());
    }
}

// 定義一個狗類
class DogNew {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public float getWeight() {
        return weight;
    }

    public void setWeight(float weight) {
        this.weight = weight;
    }

    private float weight;

}

報錯(這個報錯你可能沒出現,我自己記錄一下,總馬虎):

The   type   Dog    is   already defined

這個好解決:

1.點擊->project->clean(將你的工程文件清理一下)

2.查看包里面是不是還有其他的類名實和這個定義的類名相同,或者是其他類中定義了和這個類名一樣了,刪除一個,或者改名。是我之前創建過Dog類,這里再用相同類名就不行了。上面代碼Dog類,改成了DogNew類。OK

之后,有報錯:

編碼utf-8的不可映射字符(0xAB)

知道是編碼問題,上網搜答案一大堆。

了解一下問題出現的原因:

由於JDK是國際版的,在編譯的時候,如果我們沒有用-encoding參數指定我們的JAVA源程序的編碼格式,則javac.exe首先獲得我們操作系統默認采用的編碼格式,也即在編譯java程序時,若我們不指定源程序文件的編碼格式,JDK首先獲得操作系統的file.encoding參數(它保存的就是操作系統默認的編碼格式,如WIN2k,它的值為GBK)。

然后JDK就把我們的java源程序從file.encoding編碼格式轉化為JAVA內部默認的UNICODE格式放入內存中。然后,javac把轉換后的unicode格式的文件進行編譯成.class類文件,此時.class文件是UNICODE編碼的,它暫放在內存中。緊接着,JDK將此以UNICODE編碼的編譯后的class文件保存到我們的操作系統中形成我們見到的.class文件。

對我們來說,我們最終獲得的.class文件是內容以UNICODE編碼格式保存的類文件,它內部包含我們源程序中的中文字符串,只不過此時它己經由file.encoding格式轉化為UNICODE格式了。當我們不加設置就編譯時,相當於使用了參數:javac -encoding gbk XX.java,當然就會出現不兼容的情況。

可按一下步驟逐一排除:

方法一:

把源文件編碼修改成ASCII

1)英文版notepad++

菜單:Configure --> Options --> JDK Tools --> Compiler

1)中文版 notepad++

菜單:設置→首選項→新建,選擇編碼方式為ANSI.

 在這里也進行修改

編碼 --->以ANSI格式編碼

 

方法二:

使用-encoding 指定字符集

javac -encoding utf-8 xxxxx.java

報錯:

notepad++里面的代碼,出現中文不兼容(中文會有紅色下划線提示)

 

了解一下問題出現的原因:

Notepad有不少的插件,這個是拼寫錯誤提示的插件,一般我們不會想要它。里面的錯誤一般是為了檢測英文的拼寫錯誤,中文的注釋它就認為是錯誤的,出現大量的紅色下划線。

解決方法:

1.菜單欄 —- 插件 —- DSpellCheck ——Spell Check Document Automatically,點擊即可。

2.點擊右上角圖標,即可。(與上面效果相同)

最后,用Dos運行了這個小練習。有了IDE很少用記事本,基礎不牢靠啊。回憶了編碼的知識,也是值得的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM