जावा में क्षणिक क्षेत्र क्यों हैं?


जवाबों:


1672

transientजावा में कीवर्ड दर्शाता है कि एक क्षेत्र क्रमबद्धता का हिस्सा (जो मतलब है बचाया, नहीं होना चाहिए प्रयोग किया जाता है जैसे प्रक्रिया एक फाइल करने के लिए)।

से जावा भाषा विशिष्टता, जावा SE 7 संस्करण , खंड 8.3.1.3। transientफ़ील्ड :

चर transientको इंगित करने के लिए चिह्नित किया जा सकता है कि वे किसी वस्तु की लगातार स्थिति का हिस्सा नहीं हैं।

उदाहरण के लिए, आपके पास ऐसे फ़ील्ड हो सकते हैं जो अन्य फ़ील्ड्स से प्राप्त किए गए हैं, और केवल क्रमिक रूप से राज्य बनाए रखने के बजाय ऐसा प्रोग्राम किया जाना चाहिए।

यहां एक GalleryImageवर्ग है जिसमें एक छवि है और एक थंबनेल छवि से लिया गया है:

class GalleryImage implements Serializable
{
    private Image image;
    private transient Image thumbnailImage;

    private void generateThumbnail()
    {
        // Generate thumbnail.
    }

    private void readObject(ObjectInputStream inputStream)
            throws IOException, ClassNotFoundException
    {
        inputStream.defaultReadObject();
        generateThumbnail();
    }    
}

इस उदाहरण में, thumbnailImageएक थंबनेल छवि है जो generateThumbnailविधि को लागू करने से उत्पन्न होती है ।

thumbnailImageक्षेत्र के रूप में चिह्नित किया गया है transient, इसलिए केवल मूल imageदोनों मूल छवि और थंबनेल छवि बने बजाय धारावाहिक है। इसका मतलब यह है कि धारावाहिक वस्तु को बचाने के लिए कम भंडारण की आवश्यकता होगी। (बेशक, यह सिस्टम की आवश्यकताओं के आधार पर वांछनीय हो सकता है या नहीं भी हो सकता है - यह सिर्फ एक उदाहरण है।)

डिसेरिएलाइजेशन के समय, readObjectविधि को उस स्थिति में वापस लाने के लिए आवश्यक किसी भी ऑपरेशन को करने के लिए कहा जाता है जिस पर क्रमबद्धता हुई। यहां, थंबनेल को जेनरेट करने की आवश्यकता है, इसलिए यह readObjectविधि ओवरराइड हो जाती है , ताकि विधि को कॉल करके थंबनेल उत्पन्न हो जाएगा generateThumbnail

अतिरिक्त जानकारी के लिए, जावा सीरियलाइज़ेशन एपीआई लेख के रहस्यों की खोज करें (जो कि मूल रूप से सन डेवलपर नेटवर्क पर उपलब्ध था) में एक अनुभाग है जो उपयोग के बारे में चर्चा करता है और एक परिदृश्य प्रस्तुत करता है जहां transientकुछ क्षेत्रों के क्रमांकन को रोकने के लिए कीवर्ड का उपयोग किया जाता है।


221
लेकिन यह एक कीवर्ड क्यों है, और एनोटेशन नहीं @DoNotSerialize?
एलाजार लीबोविच

333
मुझे लगता है, यह उस समय का है जब जावा में कोई भी एनोटेशन नहीं था।
पीटर विप्रमैन

46
मुझे यह अजीब लगता है कि सीरियल करने योग्य जावा के लिए आंतरिक है। इसे एक इंटरफ़ेस या अमूर्त वर्ग के रूप में लागू किया जा सकता है, जिसमें उपयोगकर्ताओं को पढ़ने और लिखने के तरीकों को ओवरराइड करने की आवश्यकता होती है।
कालेब

7
@MJafar: readObject को आम तौर पर डीरिएरलाइजेशन मैकेनिज्म में जंजीर में डाल दिया जाता है और इस प्रकार स्वचालित रूप से कहा जाता है। इसके अलावा, कई मामलों में आपको इसे ओवरराइड करने की आवश्यकता नहीं है - डिफ़ॉल्ट कार्यान्वयन चाल करता है।
माइक एडलर

13
@caleb शायद इसलिए क्योंकि द्विआधारी प्रारूपों से निपटना स्वयं अहस्ताक्षरित पूर्णांकों की कमी के कारण जावा में अविश्वसनीय रूप से दर्दनाक है।
राइटफोल्ड

434

transientकीवर्ड को समझने से पहले , किसी को क्रमांकन की अवधारणा को समझना होगा। यदि पाठक क्रमबद्धता के बारे में जानता है, तो कृपया पहले बिंदु को छोड़ दें।

क्रमबद्धता क्या है?

सीरियलाइजेशन ऑब्जेक्ट की स्थिति को लगातार बनाने की प्रक्रिया है। इसका अर्थ है कि वस्तु की स्थिति को बाइट्स की एक धारा में परिवर्तित करने के लिए प्रयोग किया जाता है (उदाहरण के लिए किसी फ़ाइल में बाइट्स संग्रहीत करना) या स्थानांतरित करना (उदाहरण के लिए एक नेटवर्क में बाइट्स भेजना)। उसी तरह, हम वस्तु की स्थिति को बाइट्स से वापस लाने के लिए डीसेरिएलाइज़ेशन का उपयोग कर सकते हैं। यह जावा प्रोग्रामिंग में महत्वपूर्ण अवधारणाओं में से एक है क्योंकि क्रमांकन का उपयोग ज्यादातर नेटवर्किंग प्रोग्रामिंग में किया जाता है। जिन वस्तुओं को नेटवर्क के माध्यम से प्रेषित किया जाना है, उन्हें बाइट में बदलना होगा। उस उद्देश्य के लिए, प्रत्येक वर्ग या इंटरफ़ेस को इंटरफ़ेस लागू करना होगा Serializable। यह बिना किसी तरीके के एक मार्कर इंटरफ़ेस है।

अब transientकीवर्ड और उसका उद्देश्य क्या है ?

डिफ़ॉल्ट रूप से, ऑब्जेक्ट के सभी चर एक स्थिर स्थिति में परिवर्तित हो जाते हैं। कुछ मामलों में, आप कुछ चर को बनाए रखने से बचना चाह सकते हैं क्योंकि आपको उन चर को बनाए रखने की आवश्यकता नहीं है। तो आप उन चरों को घोषित कर सकते हैं transient। यदि चर के रूप में घोषित किया गया है transient, तो इसे जारी नहीं रखा जाएगा। यह transientकीवर्ड का मुख्य उद्देश्य है ।

मैं निम्नलिखित उदाहरण के साथ उपरोक्त दो बिंदुओं को समझाना चाहता हूं:

package javabeat.samples;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

class NameStore implements Serializable{
    private String firstName;
    private transient String middleName;
    private String lastName;

    public NameStore (String fName, String mName, String lName){
        this.firstName = fName;
        this.middleName = mName;
        this.lastName = lName;
    }

    public String toString(){
        StringBuffer sb = new StringBuffer(40);
        sb.append("First Name : ");
        sb.append(this.firstName);
        sb.append("Middle Name : ");
        sb.append(this.middleName);
        sb.append("Last Name : ");
        sb.append(this.lastName);
        return sb.toString();
    }
}

public class TransientExample{
    public static void main(String args[]) throws Exception {
        NameStore nameStore = new NameStore("Steve", "Middle","Jobs");
        ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("nameStore"));
        // writing to object
        o.writeObject(nameStore);
        o.close();

        // reading from object
        ObjectInputStream in = new ObjectInputStream(new FileInputStream("nameStore"));
        NameStore nameStore1 = (NameStore)in.readObject();
        System.out.println(nameStore1);
    }
}

और आउटपुट निम्नलिखित होगा:

First Name : Steve
Middle Name : null
Last Name : Jobs

मध्य नाम के रूप में घोषित किया जाता है transient, इसलिए यह लगातार भंडारण में संग्रहीत नहीं किया जाएगा।

स्रोत


25
यह उदाहरण इस कोड से लिया गया है, आप इसे यहाँ पढ़ सकते हैं: javabeat.net/2009/02/02/what-is-transient-keyword-in-java
कृष्णा

11
यह हिस्सा मुझे अजीब और संभवतः भ्रमित करता है: "इसका मतलब है कि वस्तु की स्थिति बाइट्स की एक धारा में बदल जाती है और एक फ़ाइल में संग्रहीत होती है "। यह मुझे लगता है कि ज्यादातर समय सीरियलाइज़ेशन में किसी फ़ाइल को लिखना शामिल नहीं है (मामले में: नेटवर्किंग उदाहरण जो पालन करते हैं)
गार्सिया हर्टाडो

5
उदाहरण एक बुरा है, क्योंकि मध्य नाम स्पष्ट रूप से एक क्षणिक संपत्ति नहीं है।
राफेल

1
@ राफेल मेरे लिए, उदाहरण सहायक है और कम से कम अवधारणा को समझाता है। यदि आप जागरूक हैं तो क्या आप कोई बेहतर उदाहरण प्रदान करेंगे?
चाकलादेर असफाक आरिफ

@ योडा हमारे पास NameFormatterड्राइव करने के लिए उपयोग किया जाने वाला एक संदर्भ हो सकता है toString()। या कॉन्फ़िगरेशन, या देखने, या व्यावसायिक तर्क से संबंधित कुछ भी, ... डेटा के विपरीत।
राफेल 10

84

आपको उन चर को परिभाषित करने की अनुमति देने के लिए जिन्हें आप क्रमबद्ध नहीं करना चाहते हैं।

किसी ऑब्जेक्ट में आपके पास ऐसी जानकारी हो सकती है जिसे आप क्रमबद्ध / स्थिर नहीं रखना चाहते (शायद एक मूल फैक्ट्री ऑब्जेक्ट के लिए एक संदर्भ), या शायद यह क्रमबद्ध करने का कोई मतलब नहीं है। इन्हें 'क्षणिक' के रूप में चिह्नित करने का मतलब है कि क्रमिक तंत्र इन क्षेत्रों की उपेक्षा करेगा।


36

मेरा छोटा सा योगदान:

क्षणिक क्षेत्र क्या है?
मूल रूप से, transientकीवर्ड के साथ संशोधित कोई भी क्षेत्र एक क्षणिक क्षेत्र है।

जावा में क्षणिक क्षेत्रों की आवश्यकता क्यों है? कीवर्ड आप क्रमबद्धता प्रक्रिया पर कुछ नियंत्रण देता है और आप इस प्रक्रिया से किसी वस्तु के गुण हटा सकते हैं। सीरियल ऑब्जेक्ट का उपयोग जावा ऑब्जेक्ट्स को बनाए रखने के लिए किया जाता है, अधिकतर ताकि उनके राज्यों को स्थानांतरित या निष्क्रिय होने पर संरक्षित किया जा सके। कभी-कभी, यह समझ में आता है कि किसी वस्तु की कुछ विशेषताओं को क्रमबद्ध नहीं करना है। आपको किन क्षेत्रों में क्षणिक निशान लगाने चाहिए? अब हम इसका उद्देश्य जानते हैं
transient


transientकीवर्ड और क्षणिक क्षेत्र, यह जानना महत्वपूर्ण है कि कौन से क्षेत्र क्षणिक को चिह्नित करते हैं। स्थैतिक क्षेत्रों को या तो क्रमबद्ध नहीं किया जाता है, इसलिए संबंधित कीवर्ड भी चाल चलेगा। लेकिन यह आपके वर्ग के डिजाइन को बर्बाद कर सकता है; यह वह जगह है जहाँ transientकीवर्ड बचाव के लिए आता है। मैं उन क्षेत्रों को अनुमति देने की कोशिश नहीं करता जिनके मूल्यों को दूसरों से क्रमबद्ध किया जा सकता है, इसलिए मैं उन्हें क्षणिक मानता हूं। यदि आप एक क्षेत्र कहा जाता है, तो interestजिसका मूल्य अन्य क्षेत्रों से गणना की जा सकती ( principal, rateऔर time), यह क्रमानुसार करने की कोई जरूरत नहीं है।

एक और अच्छा उदाहरण लेख शब्द मायने रखता है। यदि आप एक पूरे लेख को सहेज रहे हैं, तो शब्द गणना को बचाने के लिए वास्तव में कोई आवश्यकता नहीं है, क्योंकि यह गणना तब की जा सकती है जब लेख "संक्षिप्त" हो जाता है। या लकड़हारे के बारे में सोचो;Logger उदाहरणों को लगभग कभी भी क्रमबद्ध करने की आवश्यकता नहीं होती है, इसलिए उन्हें क्षणिक बनाया जा सकता है।


63
आपका 'सरल वाक्य' केवल एक शब्द है। यह कुछ भी नहीं समझाता है। आप इसके बिना बेहतर होंगे।
user207421

1
यह एक अच्छा स्पष्टीकरण है जहां क्षेत्र होना चाहिएtransient
चकलाडर असफाक आरव

1
ब्याज क्षेत्र और शब्द गणना क्षणिक क्षेत्रों के अच्छे उदाहरण हैं।
तरुण

1
एक और अच्छा उपयोग मामला: यदि आपकी वस्तु में सॉकेट जैसे घटक हैं और यदि आप क्रमबद्ध करना चाहते हैं तो सॉकेट का क्या होता है? यदि आप रहना चाहते हैं, तो आप सॉरी रखने के बाद क्या करेंगे? यह उस सॉकेट ऑब्जेक्ट को बनाने के लिए समझ में आता हैtransient
मोहम्मद सिद्दीक

28

एक transientचर एक चर है जिसे क्रमबद्ध नहीं किया जा सकता है।

इसका एक उदाहरण जब यह उपयोगी हो सकता है जो दिमाग में आता है, चर जो किसी विशिष्ट वस्तु उदाहरण के संदर्भ में केवल एक ही अर्थ रखते हैं और जो एक बार अमान्य हो जाते हैं और आपने ऑब्जेक्ट को निष्क्रिय कर दिया है। उस स्थिति में इसके nullबजाय उन चर का होना उपयोगी है ताकि आप जरूरत पड़ने पर उपयोगी डेटा के साथ उन्हें फिर से शुरू कर सकें।


हाँ, कुछ चीज़ जैसे "पासवर्ड या क्रेडिकार्डपिन" एक वर्ग के क्षेत्र के सदस्य।
मतीन

17

transientयह इंगित करने के लिए उपयोग किया जाता है कि वर्ग फ़ील्ड को क्रमबद्ध करने की आवश्यकता नहीं है। संभवतः सबसे अच्छा उदाहरण एक Threadक्षेत्र है। आमतौर पर ए को क्रमबद्ध करने का कोई कारण नहीं है Thread, क्योंकि इसकी स्थिति बहुत 'प्रवाह विशिष्ट' है।


अगर मैं गलत हूं तो मुझे सुधारें, लेकिन थ्रेड धारावाहिक नहीं है, इसलिए इसे वैसे भी छोड़ दिया जाएगा?
TFennis

3
@TFennis: यदि कोई श्रेणीबद्ध श्रेणी किसी श्रेणीबद्ध Aनहीं B( Threadउदाहरण के अनुसार) Aका संदर्भ देती है , तो या तो संदर्भ को चिह्नित transientकरना चाहिए क्योंकि XOR को डिफ़ॉल्ट क्रमांकन प्रक्रिया को ओवरराइड करना चाहिए ताकि BXOR के साथ कुछ उचित हो सके, यह मान लें कि केवल अनुक्रमिक उप-वर्ग Bवास्तव में संदर्भित हैं। (इसलिए वास्तविक उपवर्ग को अपने "बुरे" माता-पिता के लिए ध्यान रखना चाहिए B) XOR स्वीकार करते हैं कि क्रमांकन विफल हो जाएगा। केवल एक मामले में (क्षणिक के रूप में चिह्नित) Bस्वचालित रूप से और चुपचाप छोड़ दिया जाता है।
एएच

3
@TFennis नहीं, यह एक अपवाद का कारण होगा।
user207421

1
@AH: XOR क्यों? मुझे लगता है कि कोड उन चीजों के किसी भी संयोजन से काम करेगा, और कुछ संयोजन उपयोगी हो सकते हैं (उदाहरण के लिए डिफ़ॉल्ट क्रमांकन प्रक्रिया को ओवरराइड करना उपयोगी हो सकता है, भले ही बी के केवल क्रमिक उपवर्ग संदर्भित हों, और इसके विपरीत)।
सुपरकाट

15

देशी जावा के अलावा अन्य सीरियललाइज़ेशन सिस्टम भी इस संशोधक का उपयोग कर सकते हैं। उदाहरण के लिए, हाइबरनेट, @ ट्रान्सिएंट या क्षणिक संशोधक के साथ चिह्नित फ़ील्ड को जारी नहीं रखेगा । टेराकोटा इस संशोधक का भी सम्मान करता है।

मेरा मानना ​​है कि संशोधक का आलंकारिक अर्थ है "यह क्षेत्र केवल इन-मेमोरी उपयोग के लिए है। किसी भी तरह से इस विशेष वीएम के बाहर इसे बनाए या स्थानांतरित न करें। इसका गैर-पोर्टेबल"। यानी आप दूसरे VM मेमोरी स्पेस में इसके मूल्य पर भरोसा नहीं कर सकते। अस्थिर की तरह बहुत कुछ आप कुछ स्मृति और धागा शब्दार्थ पर भरोसा नहीं कर सकते।


14
मुझे लगता है कि transientअगर यह इस समय डिज़ाइन किया गया होता तो यह एक कीवर्ड नहीं होता। वे शायद एक एनोटेशन का उपयोग करेंगे।
जोकिम सॉर


7

इस प्रश्न का उत्तर देने से पहले, मुझे आपको SERIALIZATION समझाना होगा , क्योंकि यदि आप समझते हैं कि इसका मतलब है कि विज्ञान कंप्यूटर में क्रमांकन आप इस कीवर्ड को आसानी से समझ सकते हैं।

सीरियलाइज़ेशन जब किसी वस्तु को नेटवर्क के माध्यम से स्थानांतरित किया जाता है / भौतिक मीडिया (फ़ाइल, ...) पर सहेजा जाता है, तो वस्तु को "क्रमबद्ध" होना चाहिए। सीरियलाइज़ेशन बाइट स्थिति ऑब्जेक्ट श्रृंखला को रूपांतरित करता है। इन बाइट्स को नेटवर्क पर भेजा जाता है / सहेजा जाता है और इन बाइट्स से ऑब्जेक्ट फिर से बनाया जाता है।
उदाहरण

public class Foo implements Serializable 
{
 private String attr1;
 private String attr2;
 ...
}

अब यदि आप हस्तांतरण / नहीं करना चाहते हैं सहेजा गया इस वस्तु के क्षेत्र अतः , आप उपयोग कर सकते हैं कीवर्ड transient

private transient attr2;

उदाहरण


6

यह तब आवश्यक है जब आप कुछ संवेदनशील डेटा साझा नहीं करना चाहते हैं जो क्रमबद्धता के साथ जाते हैं।


7
संवेदनशील डेटा के अलावा अन्य उपयोग के मामले हैं जिनमें आप किसी क्षेत्र को क्रमबद्ध नहीं करना चाहते हैं। उदाहरण के लिए, आप शायद कभी भी उदाहरण के लिए Thread(@AH को क्रेडिट) को क्रमबद्ध नहीं करना चाहेंगे , जिस स्थिति में आप इसे क्षणिक के रूप में चिह्नित करेंगे। हालाँकि, एक थ्रेड संवेदनशील डेटा नहीं है और अपने आप में, यह इसे क्रमबद्ध करने के लिए कोई तार्किक अर्थ नहीं रखता है (और यह सीरियल करने योग्य नहीं है)।
glen3b

1
@ glen3b इस मामले को इस जवाब से बाहर नहीं रखा गया है। यह निश्चित रूप से आवश्यक है क्योंकि पोस्टर जिस मामले में उल्लेख किया गया है उसमें चीजें खड़ी हैं
user207421

3

Google क्षणिक अर्थ के अनुसार == केवल थोड़े समय के लिए स्थायी; नश्वर।

अब अगर आप java use transient keyword में कुछ भी क्षणिक बनाना चाहते हैं।

क्यू: जहां क्षणिक उपयोग करने के लिए?

A: आम तौर पर java में हम डेटा को वेरिएबल्स में प्राप्त करके और उन वेरिएबल्स को फाइलों में लिखकर सेव कर सकते हैं, इस प्रक्रिया को Serialization के नाम से जाना जाता है। अब यदि हम फ़ाइल में लिखे जाने वाले चर डेटा से बचना चाहते हैं, तो हम उस चर को क्षणिक बना देंगे।

transient int result=10;

नोट: क्षणिक चर स्थानीय नहीं हो सकते।


0

सीधे शब्दों में कहें तो क्षणिक जावा कीवर्ड खेतों को उनके गैर-क्षणिक क्षेत्रों के काउंटर भागों के रूप में सीरियल से सुरक्षित रखता है।

इस कोड में हमारे अमूर्त वर्ग बेसजोब को सर्पिल करने योग्य इंटरफ़ेस लागू किया गया है, हम बेसजोब से विस्तार करते हैं लेकिन हमें दूरस्थ और स्थानीय डेटा स्रोतों को क्रमबद्ध करने की आवश्यकता नहीं है; केवल संगठन का नामकरण करें और नामांकित क्षेत्र।

public abstract class BaseJob implements Serializable{
   public void ShouldRetryRun(){}
}

public class SyncOrganizationJob extends BaseJob {

   public String organizationName;
   public Boolean isSynced

   @Inject transient RemoteDataSource remoteDataSource;
   @Inject transient LocalDaoSource localDataSource;

   public SyncOrganizationJob(String organizationName) {
     super(new 
         Params(BACKGROUND).groupBy(GROUP).requireNetwork().persist());

      this.organizationName = organizationName;
      this.isSynced=isSynced;

   }
}

0

क्षणिक-कीवर्ड के लिए सरलीकृत उदाहरण कोड।

import java.io.*;

class NameStore implements Serializable {
    private String firstName, lastName;
    private transient String fullName;

    public NameStore (String fName, String lName){
        this.firstName = fName;
        this.lastName = lName;
        buildFullName();
    }

    private void buildFullName() {
        // assume building fullName is compuational/memory intensive!
        this.fullName = this.firstName + " " + this.lastName;
    }

    public String toString(){
        return "First Name : " + this.firstName
            + "\nLast Name : " + this.lastName
            + "\nFull Name : " + this.fullName;
    }

    private void readObject(ObjectInputStream inputStream)
            throws IOException, ClassNotFoundException
    {
        inputStream.defaultReadObject();
        buildFullName();
    }
}

public class TransientExample{
    public static void main(String args[]) throws Exception {
        ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("ns"));
        o.writeObject(new NameStore("Steve", "Jobs"));
        o.close();

        ObjectInputStream in = new ObjectInputStream(new FileInputStream("ns"));
        NameStore ns = (NameStore)in.readObject();
        System.out.println(ns);
    }
}

0

एक क्षेत्र जो क्षणिक संशोधक के साथ घोषित किया जाता है वह क्रमबद्ध प्रक्रिया में भाग नहीं लेगा। जब किसी वस्तु को क्रमबद्ध (किसी भी अवस्था में सहेजा जाता है) किया जाता है, तो उसके क्षणिक क्षेत्रों के मूल्यों को सीरियल प्रतिनिधित्व में नजरअंदाज कर दिया जाता है, जबकि क्षणिक क्षेत्रों के अलावा अन्य क्षेत्र क्रमबद्धता प्रक्रिया में भाग लेंगे। यह क्षणिक कीवर्ड का मुख्य उद्देश्य है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.