คำเตือน“ อักขระที่ไม่สามารถใช้งานได้สำหรับการเข้ารหัส” ใน Java


113

ฉันกำลังทำงานกับโปรเจ็กต์ Java ที่ส่งเสียงเตือนต่อไปนี้เมื่อฉันคอมไพล์:

/src/com/myco/apps/AppDBCore.java:439: warning: unmappable character for encoding UTF8
    [javac]         String copyright = "� 2003-2008 My Company. All rights reserved.";

ฉันไม่แน่ใจว่า SO จะแสดงอักขระก่อนวันที่อย่างไร แต่ควรเป็นสัญลักษณ์ลิขสิทธิ์และแสดงในคำเตือนเป็นเครื่องหมายคำถามในรูปเพชร

เป็นที่น่าสังเกตว่าอักขระปรากฏในสิ่งประดิษฐ์เอาต์พุตอย่างถูกต้อง แต่คำเตือนนั้นสร้างความรำคาญและวันหนึ่งไฟล์ที่มีคลาสนี้อาจถูกสัมผัสโดยโปรแกรมแก้ไขข้อความที่บันทึกการเข้ารหัสอย่างไม่ถูกต้อง ...

ฉันจะฉีดอักขระนี้ลงในสตริง "ลิขสิทธิ์" ได้อย่างไรเพื่อให้คอมไพเลอร์พอใจและสัญลักษณ์จะถูกเก็บรักษาไว้ในไฟล์โดยไม่มีปัญหาในการเข้ารหัสซ้ำ


สนใจที่จะรู้จริง ๆ ว่าไบต์ใดประกอบเป็นตัวละครลิขสิทธิ์นั่นคือhexdump AppDBCore.javaฉันสงสัยอยู่\u00a9แล้วและเป็นสิ่งที่ใช้ได้กับคุณบางส่วนเนื่องจากการตั้งค่าระบบของคุณ เครื่องหมายคำถามด้านบนใช้เพื่อแทนที่อักขระขาเข้าที่ไม่ทราบค่าหรือไม่สามารถระบุได้ใน Unicode hexutf8.com/…
jar

คำตอบ:


56

ใช้รูปแบบการหลีกเลี่ยง "\ uxxxx"

ตามWikipediaสัญลักษณ์ลิขสิทธิ์คือ Unicode U + 00A9 ดังนั้นบรรทัดของคุณควรอ่าน:

String copyright = "\u00a9 2003-2008 My Company. All rights reserved.";

13
โปรดระวัง \ uNNNN อักขระ ... จะถูกแยกวิเคราะห์ก่อนทำการวิเคราะห์ศัพท์ ตัวอย่างเช่นหากคุณใส่ความคิดเห็นนี้ / * c: \ unit * / ลงในโค้ดของคุณความคิดเห็นจะไม่รวบรวมอีกต่อไปเนื่องจาก "nit" ไม่ใช่เลขฐานสิบหกที่ถูกต้อง
Peter Štibraný

3
อย่างแน่นอน (สิ่งนี้จัดการได้ดีกว่าใน C # ซึ่งการหลีกเลี่ยง Unicode จะถูกนำไปใช้ในบางบริบทเท่านั้น - แต่ก็มีลำดับ \ x ที่เป็นอันตรายเช่นกันซึ่งแย่มาก)
Jon Skeet

5
ฟังดูคล้ายกับวงดนตรีมากกว่าการรักษา ปัญหาที่แท้จริงดูเหมือนว่าคุณกำลังบอกให้ javac คาดหวังไฟล์ต้นฉบับใน UTF-8 เมื่ออยู่ในการเข้ารหัสแบบไบต์เดียวเช่น ISO-8859-1 หรือ windows-1252
Alan Moore

6
@Alan M: จากประสบการณ์ของฉันมันง่ายกว่ามากที่จะทำให้แน่ใจว่าคุณจะไม่มีปัญหาด้วยการเก็บไฟล์ต้นฉบับใน ASCII มากกว่าที่จะเป็นเพื่อให้แน่ใจว่าคุณใช้การเข้ารหัสที่ถูกต้องในทุกที่ที่คุณอาจรวบรวมแหล่งที่มา (Ant, Eclipse, IDEA ฯลฯ )
Jon Skeet

6
@ จอนนั่นเป็นข้อบกพร่องพื้นฐานใน Java ความจริงที่ว่าหน่วยซอร์ส Java ถูกเข้ารหัสเป็น UTF-8, ISO 8859-1, CP1252, MacRoman หรืออะไรก็ตามจะได้รับการปฏิบัติที่เมทาดาทาภายนอกไปยังหน่วยต้นทางที่ต้องการ สิ่งนี้บังคับให้คุณอย่าลืมแก้ไขไฟล์ ant หรือ Eclipse config เป็นต้นดังที่คุณชี้ให้ถูกต้องนี่เป็นวิธีที่แย่ที่สุดในการทำเช่นนี้เนื่องจากข้อมูลเปราะบางและสูญหายได้ง่าย ภาษาที่เก็บข้อมูลเมตา (การเข้ารหัสข้อมูลเมตา) และข้อมูล (อ่าน: ซอร์สโค้ด) ไว้ด้วยกันในที่เดียวจะมีประสิทธิภาพมากกว่าในเรื่องนี้ เป็นวิธีเดียวที่มีเหตุผล
tchrist

91

ลองใช้: javac -encoding ISO-8859-1 file_name.java


1
ฉันชอบวิธีนี้ ฉันเพิ่ม "-encoding UTF-8" เป็นคอมไพล์ราร์กใน ant build.xml ของฉันและฉันยังคงได้รับ "คำเตือน: อักขระที่ไม่สามารถใช้งานไม่ได้สำหรับการเข้ารหัส ASCII" ถ้าฉันแก้ไขเป็น "-encoding jjjj" มันจะไม่คอมไพล์บ่นว่า "error: unsupported encoding: jjjj" ดังนั้นฉันจึงรู้ว่ามันรู้จัก UTF-8 แต่ดูเหมือนว่าจะถือว่าไฟล์. java เป็น ascii เฮ้อ.
dfrankow

1
ฉันลองใช้พารามิเตอร์ "การเข้ารหัส" ของงาน ant javac ปัญหาเดียวกัน มันรับรู้พารามิเตอร์ แต่ไม่สนใจมันอย่างใด
dfrankow

20
@dfrankow: คุณต้องเพิ่ม<compilerarg line="-encoding utf-8"/>ภายใต้การ<javac>โทรที่เกี่ยวข้องในBuild.xmlไฟล์ของคุณ นี่เป็นวิธีที่ไม่ดี แต่คุณไม่มีทางเลือก ดูความคิดเห็นยาว ๆ ของฉันที่ด้านบน
tchrist

ฉันมีปัญหาเดียวกันเมื่อฉันเพิ่ม compilearg ใน ant script มันใช้งานได้ฉันสร้างสิ่งนี้จาก comandline ของ windows สิ่งที่แปลกคือฉันสร้างจาก eclipse มัน warked eaven กับ compilearg ดูเหมือนว่าคราสนั้นจะดูแล ของการเข้ารหัสที่ถูกต้อง
simonC

สิ่งนี้ช่วยฉันได้ :) สำหรับ MAC OSX
อรุณอับราฮัม

44

หากคุณใช้ Maven ให้ตั้งค่า<encoding>อย่างชัดเจนในการกำหนดค่าปลั๊กอินคอมไพเลอร์เช่น

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.2</version>
            <configuration>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>

นี่เป็นแนวทางที่ถูกต้องหากผู้คนใช้ maven ในการสร้างโครงการขอบคุณสำหรับการแบ่งปัน
Shamik

2
ปลั๊กอิน javadoc จะบ่นเกี่ยวกับอักขระที่ไม่สามารถใช้งานได้ ควรตั้งค่าproject.build.sourceEncodingคุณสมบัติ
Emmanuel Bourg

ฉันใช้คุณสมบัติ project.build.sourceEncoding อยู่แล้ว แต่อย่างไรก็ตามมันไม่ได้แมปอย่างถูกต้องกับคุณสมบัติการเข้ารหัสคอมไพเลอร์ การตั้งค่านี้เป็นเคล็ดลับอย่างชัดเจน
Federico Bonelli

32

สิ่งนี้ช่วยฉันได้:

สิ่งที่คุณต้องทำคือระบุตัวแปรสภาพแวดล้อมที่เรียกว่า JAVA_TOOL_OPTIONS หากคุณตั้งค่าตัวแปรนี้เป็น -Dfile.encoding = UTF8 ทุกครั้งที่เริ่ม JVM ตัวแปรจะรับข้อมูลนี้

ที่มา: http://whatiscomingtomyhead.wordpress.com/2012/01/02/get-rid-of-unmappable-character-for-encoding-cp1252-once-and-for-all/


ว้าวมันใช้งานได้ฉันแค่เพิ่มสิ่งนี้ลงใน. bashrc ของฉันและมันก็แก้ปัญหาของฉันได้
cowboi-peng

ใช้งานได้ดีตั้งแต่บรรทัดคำสั่งที่ฉันป้อนจนถึงสร้าง: javac MyJavaFile.java -encoding utf-8 -cp .;lib\*จากนั้นเมื่อเรียกใช้ฉันไม่จำเป็นต้องเพิ่มส่วนการเข้ารหัสพิเศษนั้น
Azurespot

23

วางบรรทัดนี้ในไฟล์ yor .gradle เหนือ Java conf

apply plugin: 'java'
compileJava {options.encoding = "UTF-8"}   

คุณอาจต้องการตั้งค่าการเข้ารหัสสำหรับcompileTestJavaและสำหรับjavadocเช่นกัน
Frank Neblung

8

เวลาส่วนใหญ่เกิดข้อผิดพลาดในการคอมไพล์เมื่อคอมไพล์ไฟล์ Unicode (เข้ารหัส UTF-8)

javac -encoding UTF-8 HelloWorld.java

และคุณสามารถเพิ่มตัวเลือกการคอมไพล์นี้ใน IDE ของคุณเช่น: Intellij idea
(File> settings> Java Compiler) เพิ่มเป็นพารามิเตอร์บรรทัดคำสั่งเพิ่มเติม

ใส่คำอธิบายภาพที่นี่

-encoding: encoding ตั้งชื่อการเข้ารหัสไฟล์ต้นฉบับเช่น EUC-JP และ UTF-8 .. หากไม่ได้ระบุ -encoding จะใช้ตัวแปลงเริ่มต้นของแพลตฟอร์ม ( DOC )


8

ขั้นตอน Gradle

หากคุณใช้ Gradle คุณจะพบบรรทัดที่ใช้ปลั๊กอิน java:

apply plugin: 'java'

จากนั้นตั้งค่าการเข้ารหัสสำหรับงานคอมไพล์เป็น UTF-8:

compileJava {options.encoding = "UTF-8"}   

หากคุณมีการทดสอบหน่วยคุณอาจต้องการรวบรวมสิ่งเหล่านั้นด้วย UTF-8 ด้วย:

compileTestJava {options.encoding = "UTF-8"}

ตัวอย่าง Gradle โดยรวม

ซึ่งหมายความว่าโค้ด gradle โดยรวมจะมีลักษณะดังนี้:

apply plugin: 'java'
compileJava {options.encoding = "UTF-8"}
compileTestJava {options.encoding = "UTF-8"}

2

สิ่งนี้ได้ผลสำหรับฉัน -

    <?xml version="1.0" encoding="utf-8" ?>
<project name="test" default="compile">
    <target name="compile">
        <javac srcdir="src" destdir="classes" 
                           encoding="iso-8859-1" debug="true" />
    </target>
</project>

1

หากคุณใช้ eclipse (Eclipse สามารถใส่รหัส utf8 ให้คุณได้แม้กระทั่งคุณเขียนอักขระ utf8 คุณจะเห็นอักขระ utf8 ปกติเมื่อคุณเขียนโปรแกรม แต่พื้นหลังจะเป็นรหัส utf8)

  1. เลือกโครงการ
  2. คลิกขวาและเลือกProperties
  3. เลือกทรัพยากรบนแผงทรัพยากร (เมนูด้านบนขวาซึ่งเปิดหลังจาก 2)
  4. คุณสามารถเห็นในทรัพยากรแผง , ข้อความเข้ารหัสไฟล์เลือกอื่น ๆ ที่คุณต้องการ

PS:สิ่งนี้จะใช้ได้หากคุณกำหนดค่าคงที่ในรหัส สำหรับตัวอย่าง String test = "İİİİİıııııııçççççççç";


1
คำอธิบายของคุณ“ คุณจะเห็นอักขระ [a] utf8 ปกติเมื่อคุณ [กำลัง] เขียนโปรแกรม แต่พื้นหลัง [the] จะเป็นรหัส utf8” ไม่สมเหตุสมผล นอกจากนี้โปรดดูความคิดเห็นยาวของฉันในการตอบคำถามด้านบน
tchrist

ฉันเปลี่ยนเป็น ISO-8859-1 แต่ยังพบข้อผิดพลาดในการคอมไพล์เกี่ยวกับ "อักขระที่ไม่สามารถใช้งานได้สำหรับการเข้ารหัส UTF8"
pacoverflow

1

ฉันมีปัญหาเดียวกันโดยที่ดัชนีอักขระที่รายงานในข้อความแสดงข้อผิดพลาด java ไม่ถูกต้อง ฉัน จำกัด ให้แคบลงเหลือเพียงอักขระเครื่องหมายคำพูดคู่ก่อนตำแหน่งที่รายงานเป็นเลขฐานสิบหก 094 (ยกเลิกแทนใบเสนอราคา แต่แสดงเป็นเครื่องหมายคำพูด) แทนที่จะเป็นเลขฐานสิบหกทันทีที่ฉันสลับสำหรับตัวแปรเลขฐานสิบหกทั้งหมดก็เรียบร้อยดี


1

หากมีใครใช้ Maven Build จากพรอมต์คำสั่งก็สามารถใช้คำสั่งต่อไปนี้ได้เช่นกัน:

                    mvn -Dproject.build.sourceEncoding=UTF-8

1

สำหรับผู้ที่สงสัยว่าทำไมนี้เกิดขึ้นในบางระบบและไม่เกี่ยวกับคนอื่น ๆ (มีแหล่งที่มาเดียวกันสร้างพารามิเตอร์และอื่น ๆ ), การตรวจสอบของLANGตัวแปรสภาพแวดล้อม ฉันได้รับคำเตือน / ข้อผิดพลาดเมื่อใดLANG=C.UTF-8แต่ไม่ใช่เมื่อLANG=en_US.UTF-8ใด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.