คำหลักของ Java Transient
1. ฟังก์ชันและวิธีการใช้งานชั่วคราว
เราทุกคนรู้ว่าตราบใดที่วัตถุใช้อินเทอร์เฟซ serilizable วัตถุสามารถทำให้เป็นอนุกรม รูปแบบการทำให้เป็นอนุกรมของ Java นี้ให้ความสะดวกสบายมากมายสำหรับนักพัฒนา เราไม่จำเป็นต้องเกี่ยวข้องกับกระบวนการทำให้เป็นอนุกรมเฉพาะ ตราบใดที่คลาสนี้ใช้อินเทอร์เฟซ serilizable คุณสมบัติและวิธีการทั้งหมดของคลาสนี้จะถูกทำให้เป็นอนุกรมโดยอัตโนมัติ
อย่างไรก็ตามในกระบวนการพัฒนาจริงเรามักจะพบปัญหาดังกล่าว คุณสมบัติบางอย่างของชั้นเรียนนี้จำเป็นต้องได้รับการจัดลำดับในขณะที่คุณสมบัติอื่น ๆ ไม่จำเป็นต้องได้รับการจัดลำดับ ตัวอย่างเช่นหากผู้ใช้มีข้อมูลที่ละเอียดอ่อน (เช่นรหัสผ่านหมายเลขบัตรธนาคาร ฯลฯ ) ด้วยเหตุผลด้านความปลอดภัยเขาไม่ต้องการส่งในการดำเนินงานเครือข่าย (ส่วนใหญ่เกี่ยวข้องกับการดำเนินการแบบอนุกรม กล่าวอีกนัยหนึ่งวัฏจักรชีวิตของฟิลด์นี้อยู่ในหน่วยความจำของผู้โทรเท่านั้นและไม่ได้เขียนลงในดิสก์เพื่อการคงอยู่
ในระยะสั้นคำหลักชั่วคราวของ Java ช่วยให้เราสะดวกสบาย คุณจะต้องใช้อินเทอร์เฟซ serilizable และเพิ่มคำหลักชั่วคราวก่อนที่แอตทริบิวต์ที่ไม่จำเป็นต้องได้รับการจัดลำดับ เมื่อทำให้เป็นอนุกรมวัตถุแอตทริบิวต์นี้จะไม่ถูกทำให้เป็นอนุกรมไปยังปลายทางที่ระบุ
รหัสตัวอย่างมีดังนี้:
นำเข้า java.io.fileinputstream; นำเข้า java.io.filenotfoundException; นำเข้า java.io.fileoutputStream; นำเข้า java.io.ioException; นำเข้า java.io.ObjectInputStream; นำเข้า java.io.oBjectOutputStream; ตัวแปร * โปรดทราบว่าเมื่ออ่านลำดับของการอ่านข้อมูลจะต้องสอดคล้องกับลำดับของการจัดเก็บข้อมูล * * @author Alexia * @date 2013-10-15 * http://www.manongjc.com/article/1609.html */ผู้ใช้ใหม่ user.setUserName ("Alexia"); user.setPasswd ("123456"); System.out.println ("อ่านก่อน serializable:"); System.out.println ("ชื่อผู้ใช้:" + user.getUserName ()); System.err.println ("รหัสผ่าน:" + user.getPasswd ()); ลอง {ObjectOutputStream OS = ใหม่ ObjectOutPutStream (ใหม่ fileOutputStream ("C: /user.txt")); OS.WRITEOBJECT (ผู้ใช้); // เขียนวัตถุผู้ใช้ลงในไฟล์ os.flush (); os.close (); } catch (filenotfoundException e) {e.printStackTrace (); } catch (ioexception e) {e.printstacktrace (); } ลอง {ObjectInputStream คือ = ใหม่ ObjectInputStream (ใหม่ FileInputStream ("C: /user.txt")); user = (ผู้ใช้) คือ readObject (); // อ่านข้อมูลของผู้ใช้จากสตรีมคือ. close (); System.out.println ("/nread หลังจาก serializable:"); System.out.println ("ชื่อผู้ใช้:" + user.getUserName ()); System.err.println ("รหัสผ่าน:" + user.getPasswd ()); } catch (filenotfoundException e) {e.printStackTrace (); } catch (ioexception e) {e.printstacktrace (); } catch (classnotFoundException e) {e.printStackTrace (); }}} ผู้ใช้ในชั้นเรียนใช้ serializable {ส่วนตัวคงที่สุดท้าย Long SerialVersionUID = 8294180014912103005L; ชื่อผู้ใช้สตริงส่วนตัว; สตริงชั่วคราวส่วนตัว passwd; สตริงสาธารณะ getUserName () {ส่งคืนชื่อผู้ใช้; } โมฆะสาธารณะ setUserName (ชื่อผู้ใช้สตริง) {this.userName = ชื่อผู้ใช้; } สตริงสาธารณะ getPasswd () {return passwd; } โมฆะสาธารณะ setPasswd (สตริง passwd) {this.passwd = passwd; -ผลลัพธ์คือ:
อ่านก่อน serializable: ชื่อผู้ใช้: AlexiaPassword: 123456Read หลังจาก serializable: ชื่อผู้ใช้: AlexiaPassword: null
ฟิลด์รหัสผ่านเป็นโมฆะซึ่งหมายความว่าไม่ได้รับข้อมูลจากไฟล์ในระหว่างการ deserialization
2. สรุปการใช้งานชั่วคราว
1) เมื่อตัวแปรถูกแก้ไขโดยชั่วคราวตัวแปรจะไม่เป็นส่วนหนึ่งของการคงอยู่ของวัตถุอีกต่อไปและเนื้อหาของตัวแปรไม่สามารถเข้าถึงได้หลังจากการทำให้เป็นอนุกรม
2) คำหลักชั่วคราวสามารถแก้ไขตัวแปรเท่านั้น แต่ไม่ใช่วิธีและคลาส โปรดทราบว่าตัวแปรท้องถิ่นไม่สามารถแก้ไขได้ด้วยคำหลักชั่วคราว หากตัวแปรเป็นตัวแปรคลาสที่ผู้ใช้กำหนดคลาสจะต้องใช้อินเทอร์เฟซแบบ serializable
3) ตัวแปรที่แก้ไขโดยคำหลักชั่วคราวไม่สามารถเป็นอนุกรมได้อีกต่อไป ตัวแปรสแตติกไม่สามารถเป็นอนุกรมไม่ว่าจะถูกแก้ไขโดยชั่วคราวหรือไม่
จุดที่สามอาจทำให้เกิดความสับสนเพราะฉันพบว่าหลังจากเพิ่มคำหลักคงที่ลงในฟิลด์ชื่อผู้ใช้ในคลาสผู้ใช้ผลลัพธ์การรันโปรแกรมยังคงไม่เปลี่ยนแปลงนั่นคือชื่อผู้ใช้ของประเภทคงที่ถูกอ่านว่า "Alexia" นี่ไม่ขัดแย้งกับจุดที่สามหรือไม่? ที่จริงแล้วมันเป็นเช่นนี้: จุดที่สามถูกต้องแน่นอน (ตัวแปรคงที่ไม่สามารถเป็นอนุกรมไม่ว่าจะถูกแก้ไขโดยชั่วคราว) หลังจาก deserialization ชื่อผู้ใช้ของตัวแปรคงที่ในคลาสคือค่าของตัวแปรสแตติกที่สอดคล้องกันใน JVM ปัจจุบัน ค่านี้ไม่ได้มาจาก deserialization ใน JVM ไม่เชื่อ? ตกลงให้ฉันพิสูจน์ด้านล่าง:
นำเข้า java.io.fileinputstream; นำเข้า java.io.filenotfoundException; นำเข้า java.io.fileoutputStream; นำเข้า java.io.ioException; นำเข้า java.io.ObjectInputStream; นำเข้า java.io.oBjectOutputStream; ตัวแปร * โปรดทราบว่าเมื่ออ่านลำดับของข้อมูลการอ่านจะต้องสอดคล้องกับลำดับการจัดเก็บข้อมูล * * @author Alexia * @date 2013-10-15 * http://www.manongjc.com */คลาสสาธารณะ transienttest user.setUserName ("Alexia"); user.setPasswd ("123456"); System.out.println ("อ่านก่อน serializable:"); System.out.println ("ชื่อผู้ใช้:" + user.getUserName ()); System.err.println ("รหัสผ่าน:" + user.getPasswd ()); ลอง {ObjectOutputStream OS = ใหม่ ObjectOutPutStream (ใหม่ fileOutputStream ("C: /user.txt")); OS.WRITEOBJECT (ผู้ใช้); // เขียนวัตถุผู้ใช้ลงในไฟล์ os.flush (); os.close (); } catch (filenotfoundException e) {e.printStackTrace (); } catch (ioexception e) {e.printstacktrace (); } ลอง {// เปลี่ยนค่าชื่อผู้ใช้ก่อน deserialization user.username = "jmwang"; ObjectInputStream คือ = ใหม่ ObjectInputStream (ใหม่ FileInputStream ("C: /user.txt")); user = (ผู้ใช้) คือ readObject (); // อ่านข้อมูลของผู้ใช้จากสตรีมคือ. close (); System.out.println ("/nread หลังจาก serializable:"); System.out.println ("ชื่อผู้ใช้:" + user.getUserName ()); System.err.println ("รหัสผ่าน:" + user.getPasswd ()); } catch (filenotfoundException e) {e.printStackTrace (); } catch (ioexception e) {e.printstacktrace (); } catch (classnotFoundException e) {e.printStackTrace (); }}} ผู้ใช้ในชั้นเรียนใช้ serializable {ส่วนตัวคงที่สุดท้าย Long SerialVersionUID = 8294180014912103005L; ชื่อผู้ใช้สตริงสาธารณะ สตริงชั่วคราวส่วนตัว passwd; สตริงสาธารณะ getUserName () {ส่งคืนชื่อผู้ใช้; } โมฆะสาธารณะ setUserName (ชื่อผู้ใช้สตริง) {this.userName = ชื่อผู้ใช้; } สตริงสาธารณะ getPasswd () {return passwd; } โมฆะสาธารณะ setPasswd (สตริง passwd) {this.passwd = passwd; -ผลการดำเนินการคือ:
อ่านก่อน serializable: ชื่อผู้ใช้: AlexiaPassword: 123456Read หลังจาก serializable: ชื่อผู้ใช้: jmwangpassword: null
ซึ่งหมายความว่าค่าของชื่อผู้ใช้ของตัวแปรคงที่ในคลาส deserialized คือค่าของตัวแปรสแตติกที่สอดคล้องกันใน JVM ปัจจุบันซึ่งเป็น JMWANG ที่แก้ไขแล้วไม่ใช่ค่า Alexia ในระหว่างการทำให้เป็นอนุกรม
3. รายละเอียดการใช้งานชั่วคราว - ตัวแปรสามารถแก้ไขได้โดยคำหลักชั่วคราวจะเป็นอนุกรมได้หรือไม่?
คิดเกี่ยวกับตัวอย่างต่อไปนี้:
นำเข้า java.io.externalizable; นำเข้า java.io.file; นำเข้า java.io.fileinputstream นำเข้า java.io.fileoutputstream; นำเข้า java.io.ioException; นำเข้า Java.io.ObjectInputStream; @Date 2013-10-15 * */คลาสสาธารณะ ExternalizableTest ใช้ essformalizable {เนื้อหาสตริงส่วนตัวส่วนตัว = "ใช่ฉันจะได้รับการจัดลำดับโดยไม่คำนึงว่าฉันได้รับการแก้ไขโดยคำหลักชั่วคราวหรือไม่"; @Override โมฆะสาธารณะ writeExternal (ObjectOutput) โยน iOexception {out.writeObject (เนื้อหา); } @Override โมฆะสาธารณะ readExternal (ObjectInput in) พ่น IOException, classnotFoundException {content = (string) in.readObject (); } โมฆะคงที่สาธารณะหลัก (สตริง [] args) โยนข้อยกเว้น {externalizableTest et = new externalizableTest (); ObjectOutput out = ใหม่ ObjectOutputStream (ใหม่ fileOutputStream (ไฟล์ใหม่ ("ทดสอบ"))); out.writeObject (ET); ObjectInput in = new ObjectInputStream (ใหม่ FileInputStream (ไฟล์ใหม่ ("ทดสอบ"))); ET = (externalizableTest) in.readObject (); System.out.println (et.content); out.close (); in.close (); -ตัวแปรเนื้อหาจะเป็นอนุกรมหรือไม่? โอเคฉันได้รับคำตอบทั้งหมดใช่ผลลัพธ์คือ:
ใช่ฉันจะเป็นอนุกรมไม่ว่าฉันจะแก้ไขโดยคำหลักชั่วคราวหรือไม่ก็ตาม
ทำไมถึงเป็นเช่นนี้? มันไม่ได้บอกว่าตัวแปรของคลาสจะไม่ได้รับการจัดลำดับหลังจากได้รับการแก้ไขโดยคำหลักชั่วคราว?
เรารู้ว่าใน Java การทำให้เป็นอนุกรมวัตถุสามารถนำไปใช้งานได้โดยการใช้อินเทอร์เฟซสองแบบ หากมีการใช้งานอินเทอร์เฟซแบบ serializable การทำให้เป็นอนุกรมทั้งหมดจะดำเนินการโดยอัตโนมัติ หากมีการใช้อินเทอร์เฟซภายนอกที่สามารถใช้งานได้จะไม่มีการอนุกรมโดยอัตโนมัติ คุณต้องระบุตัวแปรที่จะทำให้เป็นอนุกรมในวิธีการ writeExternal ซึ่งไม่มีส่วนเกี่ยวข้องกับการแก้ไขโดยชั่วคราวหรือไม่ ดังนั้นตัวอย่างที่สองจะส่งออกเนื้อหาที่เริ่มต้นโดยเนื้อหาตัวแปรไม่ใช่ NULL
ขอบคุณสำหรับการอ่านฉันหวังว่ามันจะช่วยคุณได้ ขอบคุณสำหรับการสนับสนุนเว็บไซต์นี้!