জাভা টার্নারি অপারেটর বনাম </ জেডিকে 8 সামঞ্জস্যের ক্ষেত্রে


113

সম্প্রতি আমি স্প্রিং ফ্রেমওয়ার্কের উত্স কোডটি পড়ছি। আমি বুঝতে পারি না এমন কিছু এখানে চলে যায়:

public Member getMember() {
    // NOTE: no ternary expression to retain JDK <8 compatibility even when using
    // the JDK 8 compiler (potentially selecting java.lang.reflect.Executable
    // as common type, with that new base class not available on older JDKs)
    if (this.method != null) {
        return this.method;
    }
    else {
        return this.constructor;
    }
}

এই পদ্ধতিটি ক্লাসের সদস্য org.springframework.core.MethodParameter। মন্তব্যগুলি শক্ত থাকা অবস্থায় কোডটি বোঝা সহজ।

দ্রষ্টব্য: জেডিকে 8 সংকলক ব্যবহার করার পরেও জেডিকে <8 সামঞ্জস্যতা বজায় রাখার জন্য কোনও ত্রৈমাসিক অভিব্যক্তি নেই (সম্ভাব্য java.lang.reflect.Executableসাধারণ ধরণের হিসাবে নির্বাচন করা হচ্ছে, পুরনো জেডিকে-তে নতুন বেস ক্লাস উপলব্ধ নয়)

if...else...এই প্রসঙ্গে টেরিনারি এক্সপ্রেশন এবং কনস্ট্রাক্ট ব্যবহারের মধ্যে পার্থক্য কী ?

উত্তর:


103

আপনি যখন অপেরাডগুলির ধরণ সম্পর্কে চিন্তা করেন, সমস্যাটি আরও প্রকট হয়ে ওঠে:

this.method != null ? this.method : this.constructor

উভয় operands অধিকাংশ বিশেষ সাধারণ ধরন, অর্থাত্ উভয় সবচেয়ে বিশেষ ধরনের সাধারণ ধরন হয়েছে this.methodএবং this.constructor

জাভা 7-এ এটি java.lang.reflect.Memberতবে জাভা 8 শ্রেণির পাঠাগারটি একটি নতুন ধরণের প্রবর্তন করেছে java.lang.reflect.Executableযা জেনেরিকের চেয়ে বেশি বিশেষায়িত Member। সুতরাং একটি জাভা 8 শ্রেণির লাইব্রেরির সাথে ফলাফলের ধরণটি তিনবারের Executableচেয়ে বেশি হয় Member

জাভা 8 সংকলকের কয়েকটি (প্রাক-প্রকাশের) সংস্করণটি Executableটার্নারি অপারেটর সংকলন করার সময় অভ্যন্তরীণ উত্পন্ন কোডের জন্য একটি স্পষ্ট উল্লেখ প্রেরণ করেছে বলে মনে হয় । এটি একটি শ্রেণিবদ্ধ লোকে ট্রিগার করবে এবং এভাবে ClassNotFoundExceptionক্লাস লাইব্রেরি <জেডিকে 8 নিয়ে চলাকালীন রানটাইমের সময় ঘুরবে কারণ Executableকেবল জেডিকে ≥ 8 এর জন্য বিদ্যমান।

এই উত্তরে তাগির বলিভ যেভাবে উল্লেখ করেছেন, এটি জেডিকে 8-র পূর্ব-প্রকাশ সংস্করণে একটি বাগ এবং এর পরে এটি স্থির করা হয়েছে, সুতরাং if-elseকার্যনির্বাহী এবং ব্যাখ্যামূলক উভয় মন্তব্যই এখন অপ্রচলিত।

অতিরিক্ত দ্রষ্টব্য: একটি সিদ্ধান্তে আসতে পারে যে জাভা 8 এর আগে এই সংকলক বাগটি উপস্থিত ছিল তবে যাইহোক, ওপেনজেডকে 7 দ্বারা তৃতীয়টির জন্য উত্পন্ন বাইট কোড ওপেনজেডকে 8 দ্বারা উত্পন্ন বাইট কোডের সমান 8.. বাস্তবে, টাইপটির ধরণটি রানটাইমটিতে এক্সপ্রেশনটি সম্পূর্ণ নিঃশব্দে চলে যায়, কোডটি কেবলমাত্র পরীক্ষা, শাখা, লোড, কোনও অতিরিক্ত চেক না করে ফিরে পাওয়া return সুতরাং আশ্বাস দিন যে এটি কোনও সমস্যা (আর) নয় এবং প্রকৃতপক্ষে জাভা 8 এর বিকাশের সময় অস্থায়ী সমস্যা হয়েছে বলে মনে হয়।


1
তারপরে কীভাবে কোডটি জেডিকে ১.৮-এর সাথে সংকলিত জেডিকে ১.৩ চালাতে পারে। আমি জানি যে নিম্ন সংস্করণে জেডিকে সংকলিত কোডটি ঝামেলা ছাড়াই উচ্চতর সংস্করণ জেডিকে চলতে পারে ice বিপরীতভাবে?
jddxf

1
@jddxf যতক্ষণ না আপনি যথাযথ শ্রেণীর ফাইল সংস্করণ নির্দিষ্ট করেছেন এবং পরবর্তী সংস্করণগুলিতে উপলভ্য কোনও কার্যকারিতা ব্যবহার করবেন না যতক্ষণ না সবকিছু ঠিক আছে। সমস্যা দেখা দিতে বাধ্য, তবে যদি এই ধরনের ব্যবহার এই ক্ষেত্রে যেমন স্পষ্টভাবে ঘটে থাকে।
dhke

13
@ জেডিডিএক্সএফ, ব্যবহার -সোর্স / -মার্জন জাভাক বিকল্পগুলি
তাগীর ভালিভ

1
আপনাকে ধন্যবাদ, বিশেষত keেকে এবং তাগীর ভালিভ, যারা এর পুরো ব্যাখ্যা দিয়েছেন
jddxf

30

এটি আনুষ্ঠানিক জেডিকে -৮ প্রকাশের এক বছর আগে ২০১৩ সালের ৩ রা মে বেশ পুরানো প্রতিশ্রুতিতে চালু হয়েছিল । সংকলকটি times সময়ে ভারী বিকাশের মধ্যে ছিল, সুতরাং এই ধরনের সামঞ্জস্যের সমস্যা দেখা দিতে পারে। আমার ধারণা, স্প্রিং টিম সবে জেডিকে -8 বিল্ডটি পরীক্ষা করেছে এবং সমস্যাগুলি সংশোধন করার চেষ্টা করেছে, যদিও তারা আসলে সংকলক সমস্যা। জেডিকে -২ অফিসিয়াল প্রকাশের মাধ্যমে এটি অপ্রাসঙ্গিক হয়ে পড়ে। এখন এই কোডের টেরিনারি অপারেটরটি প্রত্যাশার মতো Executableঠিকঠাকভাবে কাজ করে ( সংকলিত ক্লাসের ফাইলের কোনও রেফারেন্স উপস্থিত নেই) lass

বর্তমানে অনুরূপ জিনিসগুলি জেডিকে -9 এ প্রদর্শিত হচ্ছে: কিছু কোড যা জেডিকে -8 এ সুন্দরভাবে সংকলন করা যেতে পারে তা জেডিকে -9 জাভ্যাকের সাথে ব্যর্থ হয়েছে। আমার ধারণা, এ জাতীয় বেশিরভাগ সমস্যা মুক্তির আগ পর্যন্ত স্থির থাকবে।


2
+1 টি। সুতরাং, এটি কি প্রথম বারের সংকলকটিতে বাগ ছিল? অনুশীলনের Executableকিছু দিক লঙ্ঘন করে সেই আচরণটিই যেখানে উল্লেখ করা হয়েছিল? অথবা এটি কেবল যে ওরাকল বুঝতে পেরেছিল যে তারা এই আচরণটি এমনভাবে পরিবর্তন করতে পারে যা এখনও অনুমান অনুসারে এবং পশ্চাদপদ সামঞ্জস্যতা না ভেঙে যেতে পারে?
রুখ

2
@রুখ, আমার ধারণা এটি বাগ ছিল। বাইটকোডে (হয় জাভা -8 বা পূর্বে) স্পষ্টভাবে Executableইন-টাইপ করতে টাইপ করা সম্পূর্ণ অপ্রয়োজনীয় । জাভা -8 এ এক্সপ্রেশন টাইপ অনুমানের ধারণাটি মারাত্মকভাবে পরিবর্তিত হয়েছিল এবং এই অংশটি পুরোপুরি নতুন করে লেখা হয়েছিল, সুতরাং এটি এত আশ্চর্যজনক নয় যে প্রারম্ভিক বাস্তবায়নে বাগ রয়েছে।
তাগীর ভালিভ

7

প্রধান পার্থক্য হ'ল একটি if elseব্লক একটি বিবৃতি যেখানে ত্রৈমাসিক (প্রায়শই জাভাতে শর্তসাপেক্ষ অপারেটর হিসাবে পরিচিত ) একটি অভিব্যক্তি

একটি বিবৃতিreturn কয়েকটি নিয়ন্ত্রণের পথে কলারের মতো জিনিসগুলি করতে পারে । একটি অ্যাসাইনমেন্টে একটি এক্সপ্রেশন ব্যবহার করা যেতে পারে:

int n = condition ? 3 : 2;

সুতরাং শর্তের পরে ত্রৈমাসিকের দুটি এক্সপ্রেশন একই ধরণের জন্য বাধ্যতামূলক হওয়া দরকার। এটি জাভাতে বিশেষত অটো-বক্সিং এবং স্বয়ংক্রিয় রেফারেন্স কাস্টিংয়ের সাথে কিছু অদ্ভুত প্রভাব ফেলতে পারে - এটি আপনার পোস্ট কোডটিতে মন্তব্যটি উল্লেখ করছে। আপনার ক্ষেত্রে অভিব্যক্তিগুলির জোর একটি java.lang.reflect.Executableপ্রকারের (যেমনটি সর্বাধিক বিশেষত প্রকারের ) হবে এবং এটি জাভার পুরানো সংস্করণগুলিতে নেই।

স্টাইলিস্টিকভাবে if elseকোডটি বিবৃতি-জাতীয় এবং আপনার মত প্রকাশের মতো একটি বার্নিশ ব্যবহার করে একটি ব্লক ব্যবহার করা উচিত ।

অবশ্যই, আপনি if elseযদি কোনও ল্যাম্বদা ফাংশন ব্যবহার করেন তবে আপনি কোনও ব্লককে ভাবের মতো আচরণ করতে পারেন।


6

একটি ত্রৈমাসিক অভিব্যক্তিতে রিটার্ন মান ধরণের পিতামাত্ত শ্রেণীর দ্বারা প্রভাবিত হয়, যা জাভা 8 তে বর্ণিত হিসাবে পরিবর্তিত হয়েছে।

কোনও কাস্ট কেন লেখা যায়নি তা দেখতে কষ্টসাধ্য।

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