java - চূড়ান্ত ভেরিয়েবলটিতে যদি অ্যারে থেকে অনুলিপি করা হয় তবে জাভা কেন একটি স্পষ্ট কাস্টের প্রয়োজন?




arrays casting (2)

জেএলএস ( §5.2 ) এর অবিচ্ছিন্ন প্রকাশের সাথে অ্যাসাইনমেন্ট রূপান্তরকরণের জন্য বিশেষ বিধি রয়েছে:

§15.28 , যদি অভিব্যক্তিটি byte , short , char বা int ধ্রুবক প্রকাশ ( §15.28 ) হয়:

  • ভেরিয়েবলের byte , short বা char এবং ধ্রুবক অভিব্যক্তির মান ভেরিয়েবলের ধরণের ক্ষেত্রে উপস্থাপনযোগ্য হলে একটি সংকীর্ণ আদিম রূপান্তর ব্যবহৃত হতে পারে।

যদি আমরা উপরের লিঙ্কটি অনুসরণ করি তবে আমরা এগুলি ধ্রুবক অভিব্যক্তির সংজ্ঞাতে দেখি:

  • আদিম ধরণের লিটারাল এবং String টাইপের String
  • অ্যাডিটিভ অপারেটর + এবং -
  • সাধারণ নাম ( §6.5.6.1 ) যা ধ্রুবক ভেরিয়েবলগুলি ( §4.12.4 ) উল্লেখ করে।

আমরা যদি উপরের দ্বিতীয় লিঙ্কটি অনুসরণ করি তবে আমরা তা দেখতে পাচ্ছি

আদিম প্রকার বা প্রকারের §15.28 একটি পরিবর্তনশীল, এটি final এবং একটি সংকলন-সময় ধ্রুবক এক্সপ্রেশন ( §15.28 ) দিয়ে আরম্ভ করা হয়, তাকে ধ্রুবক পরিবর্তনশীল বলা হয়

এটি অনুসরণ করে যে foo + foo কেবল তখনই fooFoo জন্য নির্ধারিত হতে fooFoo যদি foo ধ্রুবক পরিবর্তনশীল হয় । আপনার ক্ষেত্রে এটি প্রয়োগ করতে:

  • byte foo = 1; স্থির পরিবর্তনশীল সংজ্ঞা দেয় না কারণ এটি final নয়।

  • final byte foo = 1; একটি ধ্রুবক পরিবর্তনশীল সংজ্ঞায়িত করে , কারণ এটি final এবং একটি ধ্রুবক অভিব্যক্তি (একটি আদিম আক্ষরিক) দিয়ে আরম্ভ হয়।

  • final byte foo = fooArray[0]; ধ্রুবক পরিবর্তনশীল সংজ্ঞা দেয় না কারণ এটি একটি ধ্রুবক অভিব্যক্তি দিয়ে আরম্ভ হয় না।

নোট করুন যে fooFoo নিজেই final কিনা fooFoo কিছু যায় আসে না।

নিম্নলিখিত কোড দিয়ে শুরু হচ্ছে ...

byte foo = 1;
byte fooFoo = foo + foo;

আমি এই কোডটি সংকলনের চেষ্টা করার সময় আমি নিম্নলিখিত ত্রুটিটি পেয়ে যাব ...

ত্রুটি: (৫, ২)) জাভা: বেমানান প্রকারগুলি: অন্তর্নির্মিত থেকে বাইটে ক্ষতিকারক রূপান্তর

... তবে যদি foo চূড়ান্ত হয় ...

final byte foo = 1;
final byte fooFoo = foo + foo;

ফাইলটি সফলভাবে সংকলন করবে।

নিম্নলিখিত কোডে সরানো হচ্ছে ...

final byte[] fooArray = new byte[1];
fooArray[0] = 1;

final byte foo = fooArray[0];
fooArray[0] = 127;

System.out.println("foo is: " + foo);

... ছাপবে

foo is: 1

... যা ঠিক আছে। মানটি একটি চূড়ান্ত ভেরিয়েবলে অনুলিপি করা হয় এবং এটি আর পরিবর্তন করা যায় না। অ্যারেতে মানটি খেলে ফু-র মান বদলে যায় না (যেমন প্রত্যাশিত ...)।

নিম্নলিখিতগুলির জন্য কেন একটি কাস্ট প্রয়োজন?

final byte[] fooArray = new byte[1];
fooArray[0] = 1;
final byte foo = fooArray[0];
final byte fooFoo = foo + foo;

এই প্রশ্নের দ্বিতীয় উদাহরণের তুলনায় এটি কীভাবে আলাদা? সংকলক আমাকে নিম্নলিখিত ত্রুটিটি দিচ্ছে কেন?

ত্রুটি: (৫, ২)) জাভা: বেমানান প্রকারগুলি: অন্তর্নির্মিত থেকে বাইটে ক্ষতিকারক রূপান্তর

কীভাবে এটি ঘটতে পারে?


বায়ার কোড থেকে আমরা দেখতে পাচ্ছি, final সাথে ব্যবহার করার সময় এটি সংকলক ধ্রুবক ভাঁজগুলিতে কি করে?

    byte f = 1;
    // because compiler still use variable 'f', so `f + f` will 
    // be promoted to int, so we need cast
    byte ff = (byte) (f + f);
    final byte s = 3;
    // here compiler will directly compute the result and it know
    // 3 + 3 = 6 is a byte, so no need cast
    byte ss = s + s;
    //----------------------
    L0
    LINENUMBER 12 L0
    ICONST_1 // set variable to 1
    ISTORE 1 // store variable 'f'
    L1
    LINENUMBER 13 L1
    ILOAD 1 // use variable 'f'
    ILOAD 1
    IADD
    I2B        
    ISTORE 2 // store 'ff'
    L2

    LINENUMBER 14 L2
    ICONST_3 // set variable to 3
    ISTORE 3 // store 's'
    L3
    LINENUMBER 15 L3
    BIPUSH 6 // compiler just compute the result '6' and set directly
    ISTORE 4 // store 'ss'

এবং আপনি যদি আপনার চূড়ান্ত বাইটটি 127 এ পরিবর্তন করেন তবে এটিও অভিযোগ করবে:

    final byte s = 127;
    byte ss = s + s;

যে ক্ষেত্রে, সংকলক ফলাফলটি গণনা করে এবং এটি সীমা ছাড়াই জানে, সুতরাং এটি এখনও বেমানান বলে অভিযোগ করবে।

আরও:

এবং here স্ট্রিং সহ ধ্রুবক ভাঁজ সম্পর্কে আরও একটি প্রশ্ন:





byte