পূর্ণসংখ্যার অপরিবর্তনীয়


103

আমি জানি এটি সম্ভবত খুব বোকা, তবে অনেক জায়গাতেই দাবি করে যে জাভাতে পূর্ণসংখ্যা শ্রেণি অপরিবর্তনীয়, তবুও নিম্নলিখিত কোডটি:

Integer a=3;
Integer b=3;
a+=b;
System.out.println(a);

ফলাফল (প্রত্যাশিত) ফলাফল দেওয়ার ক্ষেত্রে কোনও সমস্যা ছাড়াই কার্যকর করুন So. সুতরাং কার্যকরভাবে এর মানটির পরিবর্তন হয়েছে। এর অর্থ কি পূর্ণসংখ্যার পরিবর্তনযোগ্য নয়? মাধ্যমিক প্রশ্ন এবং একটি সামান্য অফটোপিক: "অপরিবর্তনীয় ক্লাসগুলির অনুলিপি নির্মাণকারীর প্রয়োজন নেই"। কেন কেউ বোঝাতে পারছেন?


13
বর্গ অপরিবর্তনীয়, কিন্তু autoboxing করছে ভীতু ব্যাপার ঘটতে: stackoverflow.com/questions/3085332/...
wkl

ধন্যবাদ, বক্সিং গুগল করার জন্য আমার প্রয়োজনীয় কীওয়ার্ড ছিল :)
কে.স্টেফ

7
আপনি একটি চূড়ান্ত বা ধ্রুবক মান দিয়ে অপরিবর্তনীয় বিভ্রান্ত করছেন।
কোড উত্সাহী

উত্তর:


95

অপরিবর্তনীয় এর অর্থ এই নয় যে aকখনই অন্য মানের সাথে সমান হয় না। উদাহরণস্বরূপ, Stringপরিবর্তনযোগ্যও, তবে আমি এখনও এটি করতে পারি:

String str = "hello";
// str equals "hello"
str = str + "world";
// now str equals "helloworld"

strপরিবর্তিত হয়নি, বরং strএখন সম্পূর্ণ নতুনভাবে ইনস্ট্যান্টেটেড অবজেক্ট, ঠিক যেমনটি আপনার Integer। সুতরাং এর মানটি aপরিবর্তিত হয় নি, তবে এটি সম্পূর্ণ নতুন বস্তুর সাথে প্রতিস্থাপিত হয়েছিল, অর্থাৎ new Integer(6)


14
"এটি কারণ str এখন সম্পূর্ণ নতুন ইনস্ট্যান্টিয়েটেড অবজেক্ট"। অথবা পরিবর্তে, Str (ক varibale) পয়েন্ট একটি নতুন বস্তু। অবজেক্টটি নিজেই পরিবর্তনযোগ্য নয়, তবে যেহেতু ভেরিয়েবল চূড়ান্ত নয়, এটি একটি পৃথক বস্তুর দিকে নির্দেশ করতে পারে।
স্যান্ডম্যান

হ্যাঁ, এটি একটি পৃথক বস্তুর দিকে ইঙ্গিত করে যা +=অপারেশনের ফলে তাত্ক্ষণিকভাবে তৈরি হয়েছিল ।
ট্র্যাভিস ওয়েব

11
কড়া কথায় বলতে গেলে এটি কোনও নতুন অবজেক্ট হওয়ার দরকার নেই । বক্সিং ব্যবহার করে এবং সেই পদ্ধতিটি অবজেক্টের ক্যাশে বজায় রাখে । তাই ফল একটি অন পরিবর্তনশীল একটি বস্তু যা পূর্বে অস্তিত্ব হতে পারে (অথবা এটা এমনকি একই বস্তুর ... ক্ষেত্রে হতে পারে )। Integer.valueOf(int)Integer+=Integera += 0
স্টিফেন সি

4
স্ট্রিংয়ের জন্য জাভাডোক কেন স্পষ্টভাবে তার অবিচ্ছেদ্য বলছে, তবে পূর্ণসংখ্যার জন্য জাভাডোকটি তা করে না? পার্থক্যটি কেন আমি এই প্রশ্নটি পড়ছি ...
cellepo

52

aকিছু পূর্ণসংখ্যার (3) এর "রেফারেন্স", আপনার শর্টহ্যান্ডটি a+=bআসলে এটির অর্থ:

a = new Integer(3 + 3)

সুতরাং না, পূর্ণসংখ্যার পরিবর্তনীয় নয়, তবে যে ভেরিয়েবলগুলি তাদেরকে নির্দেশ করে তা হ'ল *।

* অপরিবর্তনীয় ভেরিয়েবল থাকা সম্ভব, এগুলি কীওয়ার্ড দ্বারা চিহ্নিত করা হয় finalযার অর্থ রেফারেন্সটি পরিবর্তন নাও হতে পারে।

final Integer a = 3;
final Integer b = 3;
a += b; // compile error, the variable `a` is immutable, too.

20

আপনি নির্ধারণ করতে পারেন যে অবজেক্টটি ব্যবহার করে পরিবর্তিত হয়েছে System.identityHashCode()(একটি ভাল উপায় হ'ল প্লেইনটি ব্যবহার করা ==তবে এটি মানের পরিবর্তে রেফারেন্সটি বদলেছে তা পরিষ্কার নয়)

Integer a = 3;
System.out.println("before a +=3; a="+a+" id="+Integer.toHexString(System.identityHashCode(a)));
a += 3;
System.out.println("after a +=3; a="+a+" id="+Integer.toHexString(System.identityHashCode(a)));

প্রিন্ট

before a +=3; a=3 id=70f9f9d8
after a +=3; a=6 id=2b820dda

আপনি অবজেক্টের অন্তর্নিহিত "আইডি" দেখতে aপেয়েছেন যা পরিবর্তিত হয়েছে।


4
সিস্টেম.ডিনিটিটিহ্যাশকোড () একটি খুব ভাল টিপ। এর জন্য ধন্যবাদ.
বিজ্ঞাপন ইনফিনিটাম

11

প্রাথমিক প্রশ্ন জিজ্ঞাসা,

Integer a=3;
Integer b=3;
a+=b;
System.out.println(a);

পূর্ণসংখ্যা অপরিবর্তনীয়, সুতরাং উপরে যা ঘটেছে তা হ'ল 'ক' মানের একটি নতুন রেফারেন্সে পরিবর্তিত হয়েছে The প্রাথমিক মান 3টি মেমরির কোনও রেফারেন্স ছাড়াই রেখে যায় (এটি পরিবর্তন করা হয়নি), তাই এটি আবর্জনা সংগ্রহ করা যেতে পারে।

যদি এটি কোনও স্ট্রিংয়ের সাথে ঘটে থাকে তবে এটি পূর্বে (পার্মজেন স্পেসে) ইন্টিজারের চেয়ে বেশি সময় ধরে রেফারেন্স রাখবে বলে আশা করে।


9

হ্যাঁ পূর্ণসংখ্যা পরিবর্তনযোগ্য।

এ হ'ল একটি রেফারেন্স যা কোনও বস্তুর দিকে নির্দেশ করে। আপনি যখন একটি + = 3 চালান, তখন এটি একটি আলাদা মান সহ নতুন ইন্টিজার অবজেক্টকে রেফারেন্স করতে A কে পুনরায় সাইন করে।

আপনি কখনই আসল অবজেক্টটি সংশোধন করেননি, বরং আপনি কোনও ভিন্ন অবজেক্টের উল্লেখ উল্লেখ করেছেন।

এখানে বস্তু এবং রেফারেন্স মধ্যে পার্থক্য সম্পর্কে পড়ুন ।


সরল এবং সহজেই সাধারণ মানুষের ভাষায় বলা হয়েছে, সেখানে অন্যান্য সমস্ত জটিল ব্যাখ্যা সহ :)
রওশন ফার্নান্দো

5

অপরিবর্তনীয় এর অর্থ এই নয় যে আপনি কোনও ভেরিয়েবলের মান পরিবর্তন করতে পারবেন না। এর অর্থ হ'ল যে কোনও নতুন অ্যাসাইনমেন্ট একটি নতুন অবজেক্ট তৈরি করে (এটি একটি নতুন মেমরি অবস্থান নির্ধারণ করে) এবং তারপরে মানটি নির্ধারিত হয়।

নিজের জন্য এটি বুঝতে, একটি লুপে পূর্ণসংখ্যার কার্য সম্পাদন করুন (লুপের বাইরে ঘোষিত পূর্ণসংখ্যা সহ) এবং মেমরিতে লাইভ অবজেক্টগুলি দেখুন।

অপরিবর্তনীয় বস্তুর জন্য অনুলিপি নির্মাণকারীর প্রয়োজনীয়তার কারণটি সহজ সাধারণ জ্ঞান। যেহেতু প্রতিটি অ্যাসাইনমেন্ট একটি নতুন অবজেক্ট তৈরি করে, ভাষা প্রযুক্তিগতভাবে ইতিমধ্যে একটি অনুলিপি তৈরি করে, তাই আপনাকে অন্য অনুলিপি তৈরি করতে হবে না।


2

"অপরিষ্কার ক্লাসগুলির অনুলিপি নির্মাণকারীর প্রয়োজন নেই"। কেন কেউ বোঝাতে পারছেন?

কারণটি হ'ল অপরিবর্তনীয় শ্রেণির উদাহরণ খুব কমই কপি করার (বা অনুলিপি করার কোনও পয়েন্ট) দরকার নেই। অবজেক্টের অনুলিপিটি মূল হিসাবে "একই" হওয়া উচিত এবং যদি এটি একই হয় তবে এটি তৈরি করার দরকার নেই।

কিছু অন্তর্নিহিত অনুমান যদিও আছে:

  • এটি অনুমান করে যে আপনার অ্যাপ্লিকেশন শ্রেণীর উদাহরণগুলির বস্তু পরিচয়ের কোনও অর্থ রাখে না।

  • এটি ধরে নেওয়া হয় যে ক্লাসটি ওভারলোড হয়ে গেছে equalsএবং hashCodeযাতে কোনও পদ্ধতিগুলির অনুলিপি এই পদ্ধতিগুলি অনুসারে "মূল হিসাবে একই" হয়।

হয় বা উভয়ই অনুমানগুলি মিথ্যা হতে পারে এবং এটি কোনও অনুলিপি নির্মাণকারীকে সংশোধন করতে পারে।


1

আমি এইভাবেই অপরিবর্তনীয় বুঝতে পারি

int a=3;    
int b=a;
b=b+5;
System.out.println(a); //this returns 3
System.out.println(b); //this returns 8

যদি intটি পরিবর্তিত হতে পারে তবে "এ" 8 টি মুদ্রণ করবে তবে এটি অপরিবর্তনীয় কারণ নয়, এটি 3 কেন Your আপনার উদাহরণটি কেবল একটি নতুন অ্যাসাইনমেন্ট।


0

আমি পরিষ্কার করতে পারি যে পূর্ণসংখ্যা (এবং এর অন্যান্য ধরণের যেমন ফ্লোট, শর্ট ইত্যাদি) সাধারণ নমুনা কোড দ্বারা অপরিবর্তনীয়:

কোডের উদাহরণ

public class Test{
    public static void main(String... args){
        Integer i = 100;
        StringBuilder sb = new StringBuilder("Hi");
        Test c = new Test();
        c.doInteger(i);
        c.doStringBuilder(sb);
        System.out.println(sb.append(i)); //Expected result if Integer is mutable is Hi there 1000
    }

    private void doInteger(Integer i){
        i=1000;
    }

    private void doStringBuilder(StringBuilder sb){
        sb.append(" there");
    }

}

আসল ফলাফল

ফলাফলটি তিনি প্রত্যাশিত ফলাফলের পরিবর্তে হাই হাই 100 এ এসেছেন (উভয় ক্ষেত্রে এসবি এবং আমি পরিবর্তনীয় বস্তু হ'ল) হাই হাই 1000

এটি দেখায় যে আমি প্রধানত তৈরি করা বস্তুটি সংশোধন করা হয়নি, যেখানে এসবি সংশোধিত হয়েছে।

সুতরাং স্ট্রিংবিল্ডার পারস্পরিক পরিবর্তন না করে পারস্পরিক পরিবর্তন দেখাল।

সুতরাং পূর্ণসংখ্যা অপরিবর্তনীয়। সুতরাং প্রমাণিত

শুধুমাত্র পূর্ণসংখ্যা ছাড়া অন্য একটি কোড:

public class Test{
    public static void main(String... args){
        Integer i = 100;
        Test c = new Test();
        c.doInteger(i);
        System.out.println(i); //Expected result is 1000 in case Integer is mutable
    }

    private void doInteger(Integer i){
        i=1000;
    }


}

আপনি দুটি পৃথক কাজ করছেন - পূর্ণসংখ্যাটিকে পুনরায় নিয়োগের চেষ্টা করছেন এবং স্ট্রিং বিল্ডারে কোনও পদ্ধতি কল করছেন। যদি তা করেন private void doStringBuilder(StringBuilder sb){ sb = new StringBuilder(); }তবে sbঅপরিবর্তিত।
এমটি0

আমি স্ট্রিংবিল্ডারকে (যা পরিবর্তনীয়) কেবলমাত্র জুস্টেপোজ ইন্টিজারে অপর একটি অবজেক্টের সাথে পরিবর্তন করতে পারি যা পরিবর্তনীয়। আপনি যদি চান তবে আপনি সমস্ত স্ট্রিংবিল্ডার সম্পর্কিত কোড মুছে ফেলতে পারেন এবং 100 টি দেখতে কেবল প্রিন্টআউট করতে পারেন
আশুতোষ নিগম

এটি অপরিবর্তনযোগ্যতা প্রমাণ করে না - আপনি যা করছেন তা এই উদাহরণটিকে পুনরায় হ্যাশ করছে যা দেখায় যে জাভা পাস-বাই-মান ব্যবহার করে (এবং বস্তুর জন্য পাস করা মানগুলি পয়েন্টার হয়)।
এমটি0

চেষ্টা করুনprivate void doInteger(Integer i){ System.out.println( i == 100 ); i=1000; System.out.println( i == 100 ); }
এমটি0

@ এমটি0 আপনি যখন মান দিয়ে পাস করেন স্ট্রিংবিল্ডার এখনও একই বস্তুর দিকে ইশারা করছেন তবে পূর্ণসংখ্যা একই বস্তুর সাথে সম্পর্কিত নয় এমন নতুন অনুলিপি পাস করছে। যদি আপনি doInteger এ মুদ্রণ করেন তবে আপনি মূল ফাংশন নয় বরং ফাংশনটির দ্বারা থাকা অনুলিপিটি প্রদর্শন করছেন। আমরা দেখতে চাই যে প্রধানত আমি নির্দেশিত বস্তুটি একই কিনা না। আশা করি এটি ধারণাগুলি সাফ হয়ে গেছে :) এছাড়াও স্ট্রিংবিল্ডারের অপরিবর্তনীয় সংস্করণ স্ট্রিং। আপনি যদি আমাকে এর জন্য একটি নমুনা ভাগ করে নিতে চান তবে আমাকে জানান।
আশুতোষ নিগম

0
public static void main(String[] args) {
    // TODO Auto-generated method stub

    String s1="Hi";
    String s2=s1;

    s1="Bye";

    System.out.println(s2); //Hi  (if String was mutable output would be: Bye)
    System.out.println(s1); //Bye

    Integer i=1000;
    Integer i2=i;

    i=5000;

    System.out.println(i2); // 1000
    System.out.println(i); // 5000

    int j=1000;
    int j2=j;

    j=5000;

    System.out.println(j2); // 1000
    System.out.println(j); //  5000


    char c='a';
    char b=c;

    c='d';

    System.out.println(c); // d
    System.out.println(b); // a
}

আউটপুট হল:

হাই বাই 1000 1000 1000 5000 ডি এ

সুতরাং চরটি পরিবর্তনীয়, স্ট্রিং ইন্টিজার এবং ইনট অপরিবর্তনীয়।


4
এই উত্তরটি অন্যের কাছ থেকে কোনও তথ্য সরবরাহ করে না।
জিউলিও ক্যাক্সিন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.