IntelliJ IDEA กำลังสร้าง serialVersionUID


297

สร้างค่านี้ใน IntelliJ IDEA อย่างไร

ฉันไปที่การตั้งค่า -> ข้อผิดพลาด -> ปัญหาการทำให้เป็นอันดับ -> คลาสที่ทำให้เป็นอนุกรมโดยไม่มี 'serialVersionUID' แต่ก็ยังไม่แสดงคำเตือน ผู้ปกครองคลาส PKladrBuilding ของฉันใช้ส่วนต่อประสานที่สามารถทำให้เป็นอนุกรมได้

ส่วนหนึ่งของรหัส:

public class PKladrBuilding extends PRQObject

public abstract class PRQObject extends PObject

public abstract class PObject implements Serializable

3
คุณแน่ใจหรือไม่ว่าคุณต้องการสร้างมูลค่าแทนที่จะกำหนดของคุณเอง? หากคุณกำลังสร้างคลาสใหม่ฉันขอแนะนำให้คุณกำหนดเช่น1Lเป็น ID ของคุณและเพิ่มขึ้นเมื่อมีการเปลี่ยนแปลงรูปแบบต่อเนื่องของคุณ (ดูstackoverflow.com/questions/888335/… )
Duncan Jones

1
stackoverflow.com/questions/24573643/…มีทางออกที่ดีมาก
Pankaj Kumar

คำตอบ:


588

ฉันไม่แน่ใจว่าคุณมี IntelliJ IDEA รุ่นเก่าหรือไม่ แต่ถ้าฉันไปที่เมนูไฟล์การตั้งค่า ... →การตรวจสอบปัญหาเกี่ยวกับการทำให้เป็นอนุกรม→คลาสที่ทำให้เป็นอันดับโดยไม่มีการเปิดใช้งาน

ป้อนคำอธิบายภาพที่นี่

ถ้าฉันลองชั้นหนึ่งฉันจะเห็น:

ป้อนคำอธิบายภาพที่นี่

BTW: มันไม่ได้แสดงคำเตือนให้ฉันจนกว่าฉัน{ }จะเพิ่มในตอนท้ายของแต่ละชั้นเรียนเพื่อแก้ไขข้อผิดพลาดในการรวบรวม


2
ลองFile| Invalidate Cachesหากไม่ได้ผลโปรดติดต่อ support@jetbrains.com พร้อมโครงการตัวอย่างเพื่อทำซ้ำ
CrazyCoder

1
ตรวจสอบidea.log(ช่วยเหลือ | เข้าสู่ระบบเปิดเผย ... ) สำหรับข้อยกเว้นไดเรกทอรีบ้านเข้ารหัสบนลินุกซ์เป็นที่รู้จักกันทำให้เกิดปัญหาเนื่องจากข้อผิดพลาดเคอร์เนล
CrazyCoder

1
ฉันมีข้อยกเว้นมากมายที่นั่น .. เช่น java.lang.NoClassDefFoundError: org / intellij / lang / คำอธิบายประกอบ / MagicConstant;
คิริลล์ Bazarov

2
ฉันติดตั้ง IDEA ใหม่และลบปลั๊กอินแล้วและมันก็ช่วยฉันได้ ขอบคุณมาก
คิริลล์บาซารอฟ

5
วิธีที่ฉันทำให้มันทำงานใน v15 คือการโฮเวอร์เหนือ ClassName เพื่อดูคำเตือนและเลื่อนเมาส์ไปทางรางน้ำช้าๆ ตรงจุดนั้นหลอดไฟจะปรากฏขึ้นบนหน้าจอ (ลองสองสามครั้งถ้าไม่ได้ผลตามที่ตั้งใจไว้ในครั้งแรก) จากนั้นคุณสามารถคลิกที่ตัวเลือกฟิลด์สร้างเพื่อสร้าง uid หวังว่านี่จะช่วยให้คนที่ติดอยู่กับเรื่องนี้
Niyaz

173

ติดตั้งปลั๊กอินGenerateSerialVersionUIDโดย Olivier Descout

ไปที่: เมนูไฟล์การตั้งค่าปลั๊กอินเรียกดูที่เก็บGenerateSerialVersionUID

ติดตั้งปลั๊กอินและรีสตาร์ท

ตอนนี้คุณสามารถสร้างรหัสจากเมนูรหัสสร้าง → serialVersionUID` หรือทางลัด


14
เราควรจะต้องใช้ปลั๊กอินภายนอกจริงๆเพื่อให้มันใช้งานได้หรือไม่
H.Rabiee

ใช่คุณต้องมีปลั๊กอินซึ่งเป็นส่วนหนึ่งของที่เก็บปลั๊กอิน IntelliJ อยู่แล้ว
Sileria

ทำงานให้ฉันใน Intellij IDEA 12.1
Sagar Hatekar

ได้ผลสำหรับฉันใน 13.0.2
user1978019

ใช้งานได้กับ Android Studio 0.8.9
Itai Hanski

67

ไม่มีปลั๊กอิน: คุณเพียงแค่ต้องเปิดใช้งานการเน้นใน IntelliJ:

IntelliJ Preferences -> Editor -> Inspections -> Java -> Serialization issues -> Serializable class without 'serialVersionUID'- 'OK'ธงชุดและคลิก

ตอนนี้ถ้าการดำเนินการเรียนของคุณSerializableคุณจะเห็นไฮไลท์และชื่อชั้นจะได้นำเสนอในการสร้างalt+Enterprivate static final long serialVersionUID

PS: ถ่ายจากที่นี่


4
ขอบคุณ ฉันไม่รู้ว่าทำไมฉันไม่เห็นหลอดไฟ แต่การคลิกที่ชื่อชั้นเรียนและการพิมพ์ Alt-Enter นั้นเป็นเคล็ดลับ
John S

2
คำตอบถูกขโมยจากที่นี่
Serhii Maksymchuk

นี่เป็น uptodate เพิ่มเติม
Christian Matthew

39

หลังจากใช้เวลาในการทำให้เป็นอันดับฉันพบว่าเราไม่ควรสร้างserialVersionUIDด้วยค่าสุ่มเราควรให้คุณค่าที่มีความหมาย

นี่คือความเห็นรายละเอียดเกี่ยวกับเรื่องนี้ ฉันกำลังเผชิญกับความคิดเห็นที่นี่

ที่จริงแล้วคุณไม่ควร "สร้าง" UID เวอร์ชันอนุกรม เป็น "คุณสมบัติ" โง่ที่เกิดจากความเข้าใจผิดทั่วไปว่า Java นั้นใช้ ID นั้นอย่างไร คุณควรจะให้รหัสเหล่านี้มีความหมายค่าที่อ่านได้เช่นเริ่มต้นด้วย 1L และเพิ่มขึ้นทุกครั้งที่คุณคิดว่ารุ่นใหม่ของชั้นควรแสดงรุ่นก่อนหน้าทั้งหมด (ที่อาจจะต่อเนื่องก่อนหน้านี้) ล้าสมัย ยูทิลิตีทั้งหมดที่สร้าง ID ดังกล่าวนั้นทำในสิ่งที่ JVM ทำเมื่อไม่ได้กำหนด ID: พวกมันจะสร้างค่าตามเนื้อหาของไฟล์คลาสดังนั้นจึงเกิดขึ้นกับจำนวนเต็มที่มีความยาวที่ไม่สามารถอ่านได้ หากคุณต้องการให้คลาสของคุณแตกต่างกันทุกเวอร์ชั่น (ในสายตาของ JVM) คุณไม่ควรระบุค่า serialVersionUID แม้แต่ตอนที่ JVM จะผลิตได้ทันที และคุณค่าของแต่ละรุ่นในชั้นเรียนของคุณจะไม่ซ้ำกัน จุดประสงค์ของการกำหนดค่าดังกล่าวอย่างชัดเจนคือการบอกกลไกการทำให้เป็นอนุกรมเพื่อปฏิบัติต่อเวอร์ชั่นที่แตกต่างของคลาสที่มี SVUID เหมือนกันกับว่ามันเหมือนกันหรือไม่เช่นนั้นจะไม่ปฏิเสธเวอร์ชั่นที่ต่อเนื่องกัน ดังนั้นหากคุณกำหนด ID และไม่เคยเปลี่ยน (และฉันถือว่านั่นเป็นสิ่งที่คุณทำตั้งแต่คุณพึ่งพาการสร้างอัตโนมัติและคุณอาจไม่เคยสร้าง ID ของคุณอีกครั้ง) คุณมั่นใจว่าทั้งหมด - แตกต่างกันอย่างสิ้นเชิง - รุ่นของ คลาสของคุณจะได้รับการพิจารณาเหมือนกันโดยกลไกการทำให้เป็นอันดับ นั่นคือสิ่งที่คุณต้องการ? ถ้าไม่และถ้าคุณต้องการควบคุมวิธีการรับรู้วัตถุของคุณแน่นอนคุณควรใช้ค่าง่ายๆที่คุณเองสามารถเข้าใจและอัปเดตได้อย่างง่ายดายเมื่อคุณตัดสินใจว่าคลาสมีการเปลี่ยนแปลงอย่างมีนัยสำคัญ

หวังว่านี่จะช่วยได้ โชคดี.


2
ขอบคุณฉันข้ามความจริงง่ายๆนี้มานานแล้ว!
dedek

1
จริง ๆ แล้วฉันจะสร้างserialVersionUIDใหม่ด้วยหมายเลขสุ่มใหม่เมื่อฉันไม่ต้องการสนับสนุนรุ่นเก่าในการดีซีเรียลไลซ์เซชัน บางทีฉันไม่จำเป็นต้องใช้ตัวเลขสุ่ม แต่สามารถเริ่มต้นด้วย 1 และเพิ่มขึ้นได้ อย่างไรก็ตามฉัน3Lไม่มีความหมายมากไป-3518231192373568183Lกว่านี้แล้ว ดังนั้นฉันเดาว่าโซลูชันทั้งสองทำงานคล้ายกัน แม้ว่าตัวเลขสุ่มอาจมีความได้เปรียบที่มันจะถูกปลุกด้วยประวัติศาสตร์ที่ไม่ใช่เชิงเส้นโดยมีส้อมและกิ่งก้าน
JojOatXGME

16

เพื่อสร้างมูลค่าการใช้งาน

private static final long serialVersionUID = $randomLong$L;
$END$

และจัดเตรียมตัวแปรเท็มเพลต randomLong ด้วยค่าต่อไปนี้: groovyScript ("new Random (). nextLong (). abs ()")

https://pharsfalvi.wordpress.com/2015/03/18/adding-serialversionuid-in-idea/


1
รักความคิดเห็นนี้โดยใช้เทมเพลตสดนี่เป็นวิธีแก้ปัญหาที่เร็วที่สุดและปรับแต่งได้มากที่สุด (ฉันลบ newline เช่น) ในการกำหนดค่าให้ไปที่ Android Studio> การตั้งค่า> ตัวแก้ไข> เทมเพลตสดและสร้างใหม่ที่นั่น (ไอคอนบวก) ด้วยค่านี้และใช้ตัวแปรแก้ไขเพื่อป้อนสคริปต์
hcpl

13

นอกจากนี้คุณสามารถเพิ่มเทมเพลตสดที่จะทำงานได้

วิธีทำกดCtrl+Alt+S-> "Live Templates"ส่วน -> other(หรือ w / e ที่คุณต้องการ)

จากนั้นสร้างใหม่โดยมีคำจำกัดความดังนี้:

private static final long serialVersionUID = 1L;
$END$

จากนั้นเลือกdefinitionขอบเขตและบันทึกเป็น'serial'

ตอนนี้คุณสามารถพิมพ์serialTABในคลาสของร่างกาย


3

อีกวิธีหนึ่งในการสร้าง serialVersionUID คือการใช้>Analyze >Run Inspection by Nameจากเมนูบริบท (หรือแป้นพิมพ์ลัดซึ่งเป็นctrl+ alt+ shift+ iโดยค่าเริ่มต้น) จากนั้นพิมพ์ "คลาสที่ปรับแต่งได้โดยไม่มี" serialVersionUID "" (หรือเพียงแค่พิมพ์ "serialVersionUID" และพิมพ์ล่วงหน้า ฟังก์ชั่นจะค้นหาให้คุณ

แนวคิด> วิเคราะห์> เรียกใช้การตรวจสอบตามชื่อ จากนั้นคุณจะได้รับเมนูบริบทที่คุณสามารถเลือกตำแหน่งที่จะทำการตรวจสอบ (เช่นทั้งหมดจากโมดูลเฉพาะโครงการทั้งหมดหนึ่งไฟล์ ... )

ด้วยวิธีนี้คุณไม่จำเป็นต้องตั้งกฎการตรวจสอบทั่วไปเป็นอะไรเลย


นีซนี่ทำงานให้ฉันแล้ว พบตัวแปรที่หายไปและนำเสนอตัวเลือกเพื่อเพิ่ม
arenaq

@ arenaq ดีใจนี้ช่วยคนอื่น ;-)
อเล็กซานเดอร์

2

พร้อมเวอร์ชั่น v2018.2.1

ไปที่

การตั้งค่า> ตัวแก้ไข> การตรวจสอบ> Java> ปัญหาเกี่ยวกับการทำให้เป็นอนุกรม> สลับ "คลาสที่ทำให้เป็นอนุกรมโดยไม่มี 'serialVersionUID'"

คำเตือนควรปรากฏขึ้นถัดจากการประกาศคลาส


1

ฉันใช้ Android Studio 2.1 และฉันมีความสอดคล้องที่ดีกว่าในการรับหลอดไฟด้วยการคลิกที่ชื่อชั้นเรียนและเลื่อนเมาส์ไปที่หนึ่ง


1

เพิ่มเทมเพลตสดที่เรียกว่า "ser" ไปยังกลุ่มอื่นตั้งเป็น "บังคับใน Java: declaration" และยกเลิกการเลือก "Shorten FQ names" ให้แม่แบบข้อความเพียง:

$serial$

ตอนนี้แก้ไขตัวแปรและตั้งค่าอนุกรมเป็น:

groovyScript("(System.env.JDK_HOME+'/bin/serialver -classpath '+com.intellij.openapi.fileEditor.FileDocumentManager.instance.getFile(_editor.document).path.replaceAll('/java/.*','').replaceAll('/src/','/build/classes/')+' '+_1).execute().text.replaceAll('.*: *','')",qualifiedClassName())

มันถือว่าโครงร่างโครงการ Gradle มาตรฐาน เปลี่ยน / สร้าง / เป็น / เป้าหมาย / สำหรับ Maven


1

วิธีการที่ง่ายที่สุดในปัจจุบัน: Alt+ Enterเปิด

private static final long serialVersionUID = ;

IntelliJ =จะขีดเส้นใต้ช่องว่างหลังที่ วางเคอร์เซอร์ของคุณแล้วกดalt+ Enter( Option+ Enterบน Mac) คุณจะได้รับ popover ที่ระบุว่า "Randomly Change serialVersionUID Initializer" เพียงกด Enter แล้วมันจะเติมช่องว่างนั้นด้วยการสุ่ม


0

หากคุณต้องการเพิ่ม serialVersionUID ที่ขาดหายไปสำหรับไฟล์จำนวนมาก IntelliJ IDEA อาจทำงานได้ไม่ดีนัก ฉันคิดสคริปต์ง่ายๆเพื่อบรรลุเป้าหมายนี้อย่างง่ายดาย:

base_dir=$(pwd)
src_dir=$base_dir/src/main/java
ic_api_cp=$base_dir/target/classes

while read f
do
    clazz=${f//\//.}
    clazz=${clazz/%.java/}
    seruidstr=$(serialver -classpath $ic_api_cp $clazz | cut -d ':' -f 2 | sed -e 's/^\s\+//')
    perl -ni.bak -e "print $_; printf qq{%s\n}, q{    private $seruidstr} if /public class/" $src_dir/$f
done

คุณบันทึกสคริปต์นี้พูดadd_serialVersionUID.shใน~/binโฟลเดอร์ของคุณ จากนั้นคุณเรียกใช้ในไดเรกทอรีรากของโครงการ Maven หรือ Gradle เช่น:

add_serialVersionUID.sh < myJavaToAmend.lst

.lst นี้รวมถึงรายการของไฟล์ Java เพื่อเพิ่ม serialVersionUID ในรูปแบบต่อไปนี้:

com/abc/ic/api/model/domain/item/BizOrderTransDO.java
com/abc/ic/api/model/domain/item/CardPassFeature.java
com/abc/ic/api/model/domain/item/CategoryFeature.java
com/abc/ic/api/model/domain/item/GoodsFeature.java
com/abc/ic/api/model/domain/item/ItemFeature.java
com/abc/ic/api/model/domain/item/ItemPicUrls.java
com/abc/ic/api/model/domain/item/ItemSkuDO.java
com/abc/ic/api/model/domain/serve/ServeCategoryFeature.java
com/abc/ic/api/model/domain/serve/ServeFeature.java
com/abc/ic/api/model/param/depot/DepotItemDTO.java
com/abc/ic/api/model/param/depot/DepotItemQueryDTO.java
com/abc/ic/api/model/param/depot/InDepotDTO.java
com/abc/ic/api/model/param/depot/OutDepotDTO.java

สคริปต์นี้ใช้เครื่องมือ JDK serialVer เหมาะสำหรับสถานการณ์เมื่อคุณต้องการแก้ไขคลาสจำนวนมากที่ไม่มี serialVersionUID ตั้งอยู่ในตอนแรกในขณะที่รักษาความเข้ากันได้กับคลาสเก่า

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