পদ্ধতির পরামিতি এবং স্থানীয় ভেরিয়েবলগুলির জন্য কখন চূড়ান্ত ব্যবহার করা উচিত?


171

আমি বেশ কয়েকটি রেফারেন্স পেয়েছি ( উদাহরণস্বরূপ ) যা finalযথাসম্ভব ব্যবহার করার পরামর্শ দেয় এবং আমি ভাবছি যে এটি কতটা গুরুত্বপূর্ণ। এটি মূলত পদ্ধতি পরামিতি এবং স্থানীয় ভেরিয়েবলের প্রসঙ্গে, চূড়ান্ত পদ্ধতি বা ক্লাস নয়। ধ্রুবকগুলির জন্য, এটি স্পষ্ট করে তোলে।

একদিকে, সংকলক কিছু অপ্টিমাইজেশন করতে পারে এবং এটি প্রোগ্রামারের অভিপ্রায়কে আরও পরিষ্কার করে দেয়। অন্যদিকে, এটি ভার্বোসটি যুক্ত করে এবং অপ্টিমাইজেশনগুলি তুচ্ছ হতে পারে।

এটি কি মনে রাখার চেষ্টা করা উচিত?


এখানে একটি সম্পর্কিত পোস্টে উপর তাকান হয় stackoverflow.com/questions/137868/...
mattlant


1
আমি কেবল উজ্জীবিত করছি কারণ আমি জানতাম না যে এটি পড়ার আগে পরামিতিগুলিতে কোনও পরিবর্তনকারী হিসাবে চূড়ান্ত ব্যবহার সম্ভব ছিল। ধন্যবাদ!
কিপ

পরে প্রশ্ন, তবে কেন
নওফাল

উত্তর:


178

অবসান:

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

বিবেচনা করুন কিন্তু বিচার্যভাবে ব্যবহার করুন:

  • চূড়ান্ত ক্লাস - ফ্রেমওয়ার্ক / এপিআই ডিজাইন কেবলমাত্র আমি এটি বিবেচনা করি।
  • চূড়ান্ত পদ্ধতি - মূলত চূড়ান্ত শ্রেণীর মতো। যদি আপনি টেমপ্লেট পদ্ধতির নিদর্শনগুলি ব্যবহার করেন যেমন পাগল এবং চিহ্নিত জিনিসগুলি চূড়ান্ত চিহ্নিত করছেন, আপনি সম্ভবত উত্তরাধিকারের উপর খুব বেশি নির্ভর করছেন এবং প্রতিনিধিদের পক্ষে যথেষ্ট নয়।

পায়খানা অনুভব না করা অবহেলা করুন:

  • পদ্ধতির পরামিতি এবং স্থানীয় ভেরিয়েবলগুলি - আমি খুব কমই এটি করি কারণ আমি অলস এবং আমি এটি কোডকে বিশৃঙ্খলা করে দেখতে পাই। আমি সম্পূর্ণরূপে স্বীকার করব যে চিহ্নিতকরণের পরামিতিগুলি এবং স্থানীয় ভেরিয়েবলগুলি যা আমি সংশোধন করতে যাচ্ছি না এটি "রাইটার"। আমি ইচ্ছা করি এটি ডিফল্ট ছিল। তবে এটি তা নয় এবং আমি ফাইনালটি বোঝার সাথে কোডটি আরও জটিল বোঝা। যদি আমি অন্য কারও কোডে থাকি তবে আমি সেগুলি সরিয়ে ফেলব না তবে আমি যদি নতুন কোড লিখছি তবে আমি সেগুলিতে রাখব না One একটি ব্যতিক্রম হ'ল যেখানে আপনাকে কোনও চূড়ান্ত চিহ্নিত করতে হবে যাতে আপনি অ্যাক্সেস করতে পারেন এটি একটি বেনামি অন্তর্গত শ্রেণীর মধ্যে থেকে।

  • সম্পাদনা: দ্রষ্টব্য যে একটি ব্যবহারের ক্ষেত্রে যেখানে চূড়ান্ত স্থানীয় ভেরিয়েবলগুলি আসলে @ অ্যাডাম-কোমল দ্বারা উল্লিখিত হিসাবে খুব কার্যকর হয় যখন মান if/ elseশাখাগুলিতে ভ্যারিয়াকে নির্ধারিত হয় ।


8
জোশুয়া ব্লচ যুক্তিযুক্ত যে সমস্ত বর্গ চূড়ান্ত হিসাবে সংজ্ঞায়িত করা উচিত, যদি না তারা উত্তরাধিকারের জন্য ডিজাইন করা হয়। আমি তার সাথে একমত; আমি প্রতিটি শ্রেণিতে ফাইনাল যুক্ত করি যা একটি ইন্টারফেস প্রয়োগ করে (ইউনিট পরীক্ষা তৈরি করতে সক্ষম হতে) to চূড়ান্ত হিসাবে সমস্ত সুরক্ষিত / শ্রেণিবদ্ধ পদ্ধতি হিসাবে চিহ্নিত করুন, যা ওভাররাইড হবে না।
rmaruszewski

61
জোশ ব্লচের প্রতি যথাযোগ্য সম্মানের সাথে (এবং এটি যথেষ্ট পরিমাণে), আমি সাধারণ মামলার সাথে একমত নই। কোনও এপিআই তৈরির ক্ষেত্রে অবশ্যই জিনিসগুলি লক করে দিন। আপনার নিজের কোডের ভিতরে বুই, দেয়ালগুলি খাড়া করা যা আপনাকে পরে ছিঁড়ে ফেলতে হবে এটি সময় নষ্ট।
অ্যালেক্স মিলার 13

9
এটি অবশ্যই "সময় নষ্ট" নয়, বিশেষত কারণ এটির জন্য কোনও সময় ব্যয় হয় না ... একটি অ্যাপ্লিকেশনটিতে আমি সাধারণত প্রায় সব ক্লাস finalডিফল্ট হিসাবে করি। আপনি সত্যিকারের আধুনিক জাভা আইডিই ব্যবহার না করা পর্যন্ত আপনি সুবিধাগুলি লক্ষ্য করতে পারবেন না (যদিও, আইডিইএ)।
Rogério

9
আইডিইএর কয়েকশো কোড পরিদর্শন (বাক্সের বাইরে) রয়েছে এবং এর মধ্যে কয়েকটি finalক্লাস / পদ্ধতিতে অব্যবহৃত / অপ্রয়োজনীয় কোড সনাক্ত করতে পারে । উদাহরণস্বরূপ, যদি একটি চূড়ান্ত পদ্ধতি চেক করা ব্যতিক্রম ছুঁড়ে মারার ঘোষণা দেয় তবে বাস্তবে কখনও তা ছুড়ে না দেয়, আইডিইএ আপনাকে তা বলবে এবং আপনি এই throwsধারাটি বাদ দিয়ে অপসারণ করতে পারেন । কখনও কখনও, আপনি অব্যবহৃত পুরো পদ্ধতিগুলিও সন্ধান করতে পারেন, যা যখন ওভাররাইড করা যায় না তখন এটি সনাক্তযোগ্য।
রোগারিও

8
@rmaruszewski ক্লাসগুলি চূড়ান্ত হিসাবে চিহ্নিত করা বেশিরভাগ মশকরা ফ্রেমওয়ার্কগুলিকে তাদের উপহাস করতে সক্ষম করে এইভাবে আপনাকে পরীক্ষা করা আরও কঠিন করে তোলে। আমি কেবলমাত্র ক্লাস ফাইনাল করব যদি এটি সমালোচিতভাবে গুরুত্বপূর্ণ ছিল যে এটি প্রসারিত না করা হয়।
মাইক রাইল্যান্ডার

44

এটা মনে করার জন্য আমার চেষ্টা করা উচিত এমন কিছু কি?

না, আপনি যদি Eclipse ব্যবহার করছেন, কারণ আপনি স্বয়ংক্রিয়ভাবে আপনার জন্য এই চূড়ান্ত পরিবর্তনকারীগুলি যুক্ত করতে একটি সেভ অ্যাকশন কনফিগার করতে পারেন । তারপরে আপনি কম পরিশ্রমের জন্য সুবিধা পাবেন।


3
সেভ অ্যাকশনের সাথে দুর্দান্ত টিপ, এটি সম্পর্কে জানতেন না।
স্যানিটি

1
আমি মূলত সেই উপকারটি বিবেচনা করছি যা চূড়ান্তভাবে ভুল ভেরিয়েবলকে কোডটি বাগের থেকে নিরাপদ করে তুলবে, এমন কোনও অপটিমাইজেশনের পরিবর্তে যা ঘটতে পারে বা না ঘটায়।
পিটার হিলটন

4
এটা কি সত্যিই আপনার সমস্যা? এর ফলে আপনি কীভাবে আসলে একটি বাগ এসেছিলেন?
অ্যালেক্স মিলার

1
Eclipse এ দরকারী টিপের জন্য +1 আমি মনে করি বাগগুলি এড়াতে আমাদের যথাসম্ভব চূড়ান্তভাবে ব্যবহার করা উচিত।
এমেরালডিউ

আপনি কি ইন্টেলিজিতেও এটি করতে পারেন?
Koray Tugay

15

"ফাইনাল" এর বিকাশ-সময় উপকারগুলি রান-টাইম সুবিধার জন্য কমপক্ষে তাত্পর্যপূর্ণ। এটি কোডের ভবিষ্যতের সম্পাদকদের আপনার উদ্দেশ্য সম্পর্কে কিছু বলে।

শ্রেণীর "চূড়ান্ত" চিহ্নিতকরণটি ইঙ্গিত দেয় যে আপনি ক্লাসের নকশা বা বাস্তবায়নের সময় প্রসারকে কৃপণভাবে পরিচালনা করতে কোনও প্রচেষ্টা করেননি। পাঠকরা যদি ক্লাসে পরিবর্তন করতে পারেন এবং "চূড়ান্ত" পরিবর্তনকারীকে সরাতে চান তবে তারা নিজের ঝুঁকিতেই এটি করতে পারেন। ক্লাসটি এক্সটেনশনটি ভালভাবে পরিচালনা করবে তা নিশ্চিত করার জন্য এটি তাদের উপর নির্ভর করে।

একটি ভেরিয়েবল "ফাইনাল" চিহ্নিত করা (এবং এটি কনস্ট্রাক্টারে নির্ধারণ করা) নির্ভরতা ইনজেকশন সহ কার্যকর। এটি ভেরিয়েবলের "সহযোগী" প্রকৃতি নির্দেশ করে।

একটি পদ্ধতি "চূড়ান্ত" চিহ্নিত করে বিমূর্ত ক্লাসে দরকারী। এটি স্পষ্টভাবে চিত্রিত করে যেখানে এক্সটেনশন পয়েন্টগুলি রয়েছে।


11

আমি finalজাভা আরও এক্সপ্রেশন ভিত্তিক করতে সব সময় ব্যবহার । জাভার শর্তাদি ( if,else,switch) দেখুন প্রকাশের ভিত্তিতে নয় যা আমি সর্বদা ঘৃণা করি বিশেষত যদি আপনার কার্যকরী প্রোগ্রামিংয়ের জন্য ব্যবহৃত হয় (যেমন এমএল, স্কালা বা লিস্প)।

সুতরাং শর্তাদি ব্যবহার করার সময় আপনার সর্বদা (আইএমএইচও) চূড়ান্ত পরিবর্তনশীলগুলি ব্যবহার করার চেষ্টা করা উচিত।

আমাকে যদি আপনি একটি উদাহরণ দিতে:

    final String name;
    switch(pluginType) {
        case CANDIDATE_EXPORT:
            name = "Candidate Stuff";
            break;
        case JOB_POSTING_IMPORT:
            name = "Blah";
            break;
        default:
            throw new IllegalStateException();
    }

এখন অন্য caseবিবৃতি যুক্ত করুন এবং nameসংকলক সেট না করা ব্যর্থ হবে। আপনি প্রতিটি ক্ষেত্রে (যদি আপনি ভেরিয়েবল সেট করে থাকেন) না ভাঙেন তবে সংকলকটিও ব্যর্থ হবে। এটি আপনাকে জাভাটিকে লিস্পের মত letপ্রকাশের সাথে খুব অনুরূপ করতে এবং এটি কার্যকর করে যাতে আপনার কোডটি ব্যাপকভাবে ইনডেন্টেড না হয় (লেক্সিকাল স্কোপিং ভেরিয়েবলের কারণে)।

এবং @ রিকার্স উল্লিখিত হিসাবে (তবে আপাতদৃষ্টিতে -১ আমাকে) আপনি String name finalসংকলক ত্রুটিটি অর্জনের জন্য পূর্ববর্তী কাজটি করতে পারেন (যা আমি কখনই বলিনি যে আপনি পারেননি) তবে আপনি সহজেই সংকলক ত্রুটিটি স্যুইচটির পরে নাম নির্ধারণ করতে যেতে পারেন বিবৃতি যা অভিব্যক্তি শব্দার্থকে দূরে সরিয়ে দেয় বা আরও ভুলে breakযা যার ফলে আপনি কোনও ত্রুটি সৃষ্টি করতে পারবেন না (@Recurse যা বলেন তা সত্ত্বেও) final:

    String name;
    switch(pluginType) {
        case CANDIDATE_EXPORT:
            name = "Candidate Stuff";
            //break; whoops forgot break.. 
            //this will cause a compile error for final ;P @Recurse
        case JOB_POSTING_IMPORT:
            name = "Blah";
            break;
    }
    // code, code, code
    // Below is not possible with final
    name = "Whoops bug";

বাগ সেটিং নামটির কারণে (ভুলে যাওয়ার পাশাপাশি breakযা অন্য কোনও বাগও রয়েছে) আমি এখন দুর্ঘটনাক্রমে এটি করতে পারি:

    String name;
    switch(pluginType) {
        case CANDIDATE_EXPORT:
            name = "Candidate Stuff";
            break;
        //should have handled all the cases for pluginType
    }
    // code, code, code
    // Below is not possible with final
    name = "Whoops bug";

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

ওকামালে উপরোক্ত:

type plugin = CandidateExport | JobPostingImport

let p = CandidateExport

let name = match p with
    | CandidateExport -> "Candidate Stuff"
    | JobPostingImport -> "Blah" ;;

match ... with ...একটি ফাংশন অর্থাত অভিব্যক্তি মত মূল্যায়ন করে। আমাদের সুইচ স্টেটমেন্টটি দেখতে কেমন তা লক্ষ্য করুন।

এখানে স্কিমের একটি উদাহরণ (র‌্যাকেট বা চিকেন):

(define name 
    (match b
      ['CandidateExport "Candidate Stuff"]
      ['JobPostingImport "Blah"]))

1
জাভা সংকলক ইতিমধ্যে আপনাকে একটি "নাম সম্ভাব্য অবিচ্ছিন্ন" ত্রুটি দেবে এবং চূড়ান্ত বা তার সাথে সংকলন করতে অস্বীকার করবে।
পুনরাবৃত্তি করুন

4
হ্যাঁ তবে ফাইনালটি শেষ করে আপনি যে কোনও সময় এটি পুনরায় সেট করতে পারেন। আমি আসলে এই ঘটতে যেখানে একজন বিকাশকারী একটি পরিণত দেখেছি else if (...)একটি মধ্যে if(...)এবং এইভাবে পরিবর্তনশীল রিসেট। আমি তাকে দেখিয়েছি যে চূড়ান্ত পরিবর্তনশীল সঙ্গে কখনও ঘটেনি। মূলত finalআপনাকে একবারে এবং একবারে কেবল পরিবর্তনশীল বরাদ্দ করতে বাধ্য করে ... সুতরাং: পি
অ্যাডাম জেন্ট

9

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

তারপরে আপনি পুনরায় ব্যবহৃত ভেরিয়েবলগুলি ব্যবহারের বিন্দুর কাছাকাছি ঘোষণা করে পুনরায় ব্যবহৃত ভেরিয়েবলগুলি প্রতিস্থাপন করে কিছু ত্রুটি সমাধান করতে পারেন। তারপরে আপনি দেখতে পেয়েছেন যে আপনি স্কেপিংয়ের ধনুর্বন্ধনীগুলিতে পুরো পদ্ধতির পুরো অংশটি গুটিয়ে রাখতে পারেন এবং হঠাৎ আপনি "এক্সট্র্যাক্ট মেথড" থেকে দূরে একটি আইডিই কিপ্রেস এবং আপনার দৈত্যটি আরও বোধগম্য হয়ে উঠেছে।

আপনার পদ্ধতি থাকলে না ইতিমধ্যে একটি অচল রেক, আমি কাপড় বলা রেক পরিণত থেকে মানুষ নিরুৎসাহিত করতে চূড়ান্ত উপার্জন মান সেখানে হতে পারে অনুমান; তবে যদি এটি একটি স্বল্প পদ্ধতি (দেখুন: অভাবনীয় নয়) তবে আপনি প্রচুর ভার্বোসিসিটি যুক্ত করার ঝুঁকি রাখেন। বিশেষত, জাভা ফাংশন স্বাক্ষরগুলি 80 টি অক্ষরে ফিট করার পক্ষে যথেষ্ট শক্ত কারণ এটি যুক্তি অনুসারে ছয়টি যুক্ত না করেই!


1
অত্যন্ত বৈধ শেষ পয়েন্ট, যদিও আমি দীর্ঘ সময় আগে ৮০ টি চরিত্রের সীমা ছেড়ে দিয়েছিলাম কারণ গত দশ বছরে স্ক্রিন রেজোলিউশন কিছুটা বদলেছে। আমি সহজেই স্ক্রোল না করে আমার স্ক্রিনে 300 টি চর লাইনে ফিট করতে পারি। তবুও, finalপ্রতিটি প্যারামিটারের আগে না পঠনযোগ্যতা অবশ্যই ভাল ।
ব্রিম্বরিয়াম

8

ঠিক আছে, এটি আপনার স্টাইলের উপর নির্ভর করে ... আপনি যদি ভেরিয়েবলটি সংশোধন করবেন না এমন সময় আপনি যদি ফাইনাল দেখতে পছন্দ করেন তবে এটি ব্যবহার করুন। যদি আপনি এটি দেখতে পছন্দ করেন না ... তবে এটি ছেড়ে দিন।

আমি ব্যক্তিগতভাবে যথাসম্ভব কম ভারবোসিটি পছন্দ করি, তাই আমি অতিরিক্ত কীওয়ার্ডগুলি ব্যবহার করা এড়াতে চাই যা সত্যই প্রয়োজনীয় নয়।

আমি যদিও গতিশীল ভাষাগুলি পছন্দ করি তাই এটি ভারবসিততা এড়াতে আমার পক্ষে সম্ভবত কোনও আশ্চর্যের বিষয় নয়।

সুতরাং, আমি বলতে চাই যে আপনি যে দিকে ঝুঁকছেন সেদিকেই বাছুন এবং কেবল এটির সাথে চলুন (যাই হোক না কেন, সামঞ্জস্যপূর্ণ হওয়ার চেষ্টা করুন)।


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


6

দুর্ঘটনাক্রমে প্যারামিটারের মানটি এড়াতে এবং একটি সূক্ষ্ম বাগ প্রবর্তন করতে এটি পরামিতিগুলিতে কার্যকর। আমি এই প্রস্তাবটি উপেক্ষা করার জন্য ব্যবহার করি তবে কিছু 4 ঘন্টা ব্যয় করার পরে। একটি ভয়াবহ পদ্ধতিতে (শত শত লাইন কোড এবং একাধিক ফোর সহ, নেস্টেড ifs এবং সমস্ত ধরণের খারাপ অভ্যাস সহ) আমি আপনাকে এটি করার পরামর্শ দিচ্ছি।

 public int processSomethingCritical( final int x, final int y ){
 // hundreds of lines here 
     // for loop here...
         int x2 = 0;
        x++; // bug aarrgg...
 // hundreds of lines there
 // if( x == 0 ) { ...

 }

অবশ্যই একটি নিখুঁত বিশ্বে এটি ঘটবে না, তবে .. ভাল .. কখনও কখনও আপনাকে অন্যদের কোড সমর্থন করতে হবে। :(


2
এই পদ্ধতিতে চূড়ান্ত অনুপস্থিতির চেয়ে আরও গুরুতর সমস্যা রয়েছে। এটি অসম্ভব অসম্ভব, যদিও এটি অসম্ভব নয়, তবে কোনও পদ্ধতির এতটাই বিশৃঙ্খল হওয়ার জন্য যে এই ধরণের ত্রুটিগুলি ঘটতে পারে তার একটি ভাল কারণ রয়েছে। পরিবর্তনশীল নামগুলির মধ্যে রাখা একটি ছোট্ট চিন্তা এই ধরণের দুর্ঘটনার দিকে দীর্ঘ পথ পাবে।
ykaganovich

2
যদি আপনার একক পদ্ধতিতে "কয়েকশ লাইনের কোড" থাকে তবে আপনি এটি কয়েকটি ছোট পদ্ধতিতে বিভক্ত করতে চাইতে পারেন।
স্টিভ কুও

5

আপনি যদি কোনও অ্যাপ্লিকেশন লিখছেন যে কাউকে কোডটি পড়তে হবে পরে, 1 বছর বলুন, তবে হ্যাঁ, ভেরিয়েবলের উপর চূড়ান্ত ব্যবহার করুন যা পুরো সময় পরিবর্তন করা উচিত নয়। এটি করার মাধ্যমে আপনার কোডটি আরও "স্ব-ডকুমেন্টিং" হবে এবং আপনি অন্যান্য বিকাশকারীদের জন্য স্থানীয় অস্থায়ী পরিবর্তনশীল হিসাবে স্থানীয় ধ্রুবক ব্যবহার করার মতো নির্বোধ কাজ করার সুযোগও হ্রাস করেন reduce

যদি আপনি কিছু নিক্ষিপ্ত কোড লিখছেন, তবে, না, সমস্ত ধ্রুবক সনাক্ত করতে এবং এগুলিকে চূড়ান্ত করতে বিরক্ত করবেন না।


4

আমি যতটা পারি চূড়ান্ত ব্যবহার করব। আপনি যদি অনিচ্ছাকৃতভাবে ক্ষেত্রটি পরিবর্তন করেন তবে এটি করার ফলে ফ্ল্যাগ হবে। আমি চূড়ান্ত করার জন্য পদ্ধতি পরামিতি সেট করেছি। এটি করার ফলে আমি জাভাটি মূল্য দিয়ে ভুলে যাওয়া কোনও পরামিতি 'সেট' করার চেষ্টা করার সময় আমি যে কোডটি নিয়েছিলাম তা থেকে আমি বেশ কয়েকটি বাগ পেয়েছি।


2

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

আপনার সুনির্দিষ্ট প্রশ্নের উত্তর দেওয়ার জন্য, কোডটি প্রয়োজনীয় না হওয়া পর্যন্ত আমি উদাহরণ বা স্থানীয় পরিবর্তনশীল (পদ্ধতি প্যারামিটার সহ) চূড়ান্ত করার বিষয়ে বিরক্ত করব না (যেমন ভেরিয়েবলটি অভ্যন্তরীণ শ্রেণীর থেকে উল্লেখ করা হয়) বা কিছু জটিল যুক্তি স্পষ্ট করতে পারি না।

উদাহরণস্বরূপ ভেরিয়েবলগুলির জন্য, আমি তাদের চূড়ান্ত করব যদি তারা যুক্তিযুক্ত ধ্রুবক হয়।


2

চলকটির জন্য অনেকগুলি ব্যবহার রয়েছে final। এখানে মাত্র কয়েক

ফাইনাল কনস্ট্যান্টস

 public static class CircleToolsBetter {
     public final static double PI = 3.141;
        public double getCircleArea(final double radius) {
          return (Math.pow(radius, 2) * PI);
        }
    }

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

ফাইনাল ভেরিয়েবল

public static String someMethod(final String environmentKey) {
    final String key = "env." + environmentKey;
    System.out.println("Key is: " + key);
    return (System.getProperty(key));

  }

}

এই শ্রেণিতে আপনি একটি স্কোপড চূড়ান্ত ভেরিয়েবল তৈরি করেন যা প্যারামিটার এনভায়রনমেন্ট কীতে একটি উপসর্গ যুক্ত করে। এই ক্ষেত্রে, চূড়ান্ত পরিবর্তনশীল কেবলমাত্র কার্যকর করার সুযোগের মধ্যে চূড়ান্ত হয়, যা পদ্ধতির প্রতিটি প্রয়োগের ক্ষেত্রে পৃথক। প্রতিবার পদ্ধতি প্রবেশ করার পরে চূড়ান্তটি পুনর্গঠন করা হয়। এটি নির্মাণের সাথে সাথে, পদ্ধতিটি কার্যকর করার সুযোগের সময় এটি পরিবর্তন করা যাবে না। এটি আপনাকে পদ্ধতির সময়কালের জন্য কোনও পদ্ধতিতে একটি ভেরিয়েবল ঠিক করতে দেয়। নিচে দেখ:

public class FinalVariables {


  public final static void main(final String[] args) {
    System.out.println("Note how the key variable is changed.");
    someMethod("JAVA_HOME");
    someMethod("ANT_HOME");
  }
}

ফাইনাল কনস্ট্যান্টস

public double equation2Better(final double inputValue) {
    final double K = 1.414;
    final double X = 45.0;

double result = (((Math.pow(inputValue, 3.0d) * K) + X) * M);
double powInputValue = 0;         
if (result > 360) {
  powInputValue = X * Math.sin(result); 
} else {
  inputValue = K * Math.sin(result);   // <= Compiler error   
}

এগুলি বিশেষত কার্যকর যখন আপনি কোডগুলির দীর্ঘ লাইনে থাকবেন এবং এটি সংকলক ত্রুটি তৈরি করবে যাতে কোনও ব্যক্তি দুর্ঘটনাক্রমে পরিবর্তনশীল পরিবর্তন করতে না পারলে আপনি যুক্তি / ব্যবসায় ত্রুটির দিকে না চলে।

চূড়ান্ত সংগ্রহ

বিভিন্ন ক্ষেত্রে যখন আমরা সংগ্রহের কথা বলছি তখন আপনার সেগুলি অবিরামযোগ্য হিসাবে সেট করা দরকার।

 public final static Set VALID_COLORS; 
    static {
      Set temp = new HashSet( );
      temp.add(Color.red);
      temp.add(Color.orange);
      temp.add(Color.yellow);
      temp.add(Color.green);
      temp.add(Color.blue);
      temp.add(Color.decode("#4B0082")); // indigo
      temp.add(Color.decode("#8A2BE2")); // violet
      VALID_COLORS = Collections.unmodifiableSet(temp);
    }

অন্যথায়, আপনি যদি এটি অবিস্মরণীয় হিসাবে সেট না করেন:

Set colors = Rainbow.VALID_COLORS;
colors.add(Color.black); // <= logic error but allowed by compiler

চূড়ান্ত শ্রেণি এবং চূড়ান্ত পদ্ধতি যথাক্রমে প্রসারিত বা ওভাররাইট করা যায় না।

সম্পাদনা: নিবন্ধকরণ সংক্রান্ত শেষ শ্রেণীর সমস্যা সমাধানের জন্য:

ক্লাস ফাইনাল করার দুটি উপায় রয়েছে। প্রথমটি শ্রেণীর ঘোষণায় কীওয়ার্ড ফাইনালটি ব্যবহার করা হয়:

public final class SomeClass {
  //  . . . Class contents
}

ক্লাস ফাইনাল করার দ্বিতীয় উপায় হ'ল এর সমস্ত নির্মাণকারীকে ব্যক্তিগত হিসাবে ঘোষণা করা:

public class SomeClass {
  public final static SOME_INSTANCE = new SomeClass(5);
  private SomeClass(final int value) {
  }

এই পরীক্ষার ক্লাসটি দেখানোর জন্য এটি চূড়ান্তভাবে চূড়ান্ত কিনা তা সন্ধান করে যদি এটিকে চূড়ান্ত চিহ্নিত করা আপনার সমস্যাটিকে বাঁচায়। প্রথম নজরে পাবলিক দেখায়।

public class Test{
  private Test(Class beanClass, Class stopClass, int flags)
    throws Exception{
    //  . . . snip . . . 
  }
}

দুর্ভাগ্যক্রমে, যেহেতু ক্লাসের একমাত্র নির্মাণকারী ব্যক্তিগত, তাই এই শ্রেণিটি বাড়ানো অসম্ভব। টেস্ট ক্লাসের ক্ষেত্রে ক্লাসটি ফাইনাল হওয়ার কোনও কারণ নেই। অন্তর্ভুক্ত চূড়ান্ত ক্লাস কীভাবে সমস্যা সৃষ্টি করতে পারে তার একটি দুর্দান্ত উদাহরণ টেস্ট ক্লাস।

সুতরাং আপনি নির্ধারিতভাবে এটির নির্মাণকারীকে ব্যক্তিগত করে ক্লাস ফাইনাল তৈরি করার সময় আপনার এটি চূড়ান্ত হিসাবে চিহ্নিত করা উচিত।


1

আপনার উল্লেখ হিসাবে কিছুটা বাণিজ্য বন্ধ থাকলেও আমি অন্তর্নিহিত ব্যবহারের চেয়ে কোনও কিছুর স্পষ্ট ব্যবহার পছন্দ করি। এটি ভবিষ্যতের কোড রক্ষণাবেক্ষণকারীদের জন্য কিছুটা অস্পষ্টতা দূর করতে সহায়তা করবে - এমনকি যদি তা কেবল আপনিই হন।


1

আপনার যদি অভ্যন্তরীণ (বেনামে) ক্লাস থাকে এবং পদ্ধতিটি সমন্বিত পদ্ধতির ভেরিয়েবলটি অ্যাক্সেস করতে পারে তবে আপনার সেই পরিবর্তনশীলটি চূড়ান্ত হিসাবে থাকা দরকার।

তা ছাড়া, আপনি যা বলেছেন তা সঠিক।


এখন জাভা 8 কার্যকর চূড়ান্ত ভেরিয়েবলগুলির সাথে নমনীয়তা সরবরাহ করে।
রবীন্দ্র বাবু

0

finalকোনও ভেরিয়েবলের জন্য কীওয়ার্ড ব্যবহার করুন যদি আপনি সেই পরিবর্তনশীল হিসাবে তৈরি করে থাকেনimmutable

ভেরিয়েবলটিকে চূড়ান্ত হিসাবে ঘোষণা করে, এটি বিকাশকারীদের অত্যন্ত বহু-থ্রেডযুক্ত পরিবেশে ভেরিয়েবলের সম্ভাব্য পরিবর্তন সংক্রান্ত সমস্যাগুলি বাতিল করতে সহায়তা করে।

জাভা 8 রিলিজের সাথে, " effectively final variable" নামে আমাদের আরও একটি ধারণা রয়েছে । একটি চূড়ান্ত নয় এমন চূড়ান্তটি চূড়ান্ত পরিবর্তনশীল হিসাবে উত্তোলন করতে পারে।

ল্যাম্বডা এক্সপ্রেশন থেকে স্থানীয় ভেরিয়েবলগুলি অবশ্যই চূড়ান্ত বা কার্যকরভাবে চূড়ান্ত হতে হবে

স্থানীয় ব্লকে সূচনা করার পরে যদি তা পরিবর্তন না করা হয় তবে একটি পরিবর্তনশীল কার্যকর চূড়ান্ত হিসাবে বিবেচিত হয়। এর অর্থ আপনি এখন কোনও বেনাম শ্রেণীর বা ল্যাম্বডা এক্সপ্রেশনের ভিতরে চূড়ান্ত কীওয়ার্ড ছাড়াই স্থানীয় পরিবর্তনশীল ব্যবহার করতে পারেন, তবে তাদের অবশ্যই কার্যকরভাবে চূড়ান্ত হতে হবে provided

জাভা 7 অবধি আপনি কোনও বেনাম শ্রেণীর ভিতরে একটি চূড়ান্ত-স্থানীয় স্থানীয় পরিবর্তনশীল ব্যবহার করতে পারবেন না, তবে জাভা 8 থেকে আপনি পারবেন

এই নিবন্ধটি দেখুন


-1

প্রথমত, চূড়ান্ত কীওয়ার্ডটি একটি পরিবর্তনশীল ধ্রুবক তৈরি করতে ব্যবহৃত হয়। ধ্রুব অর্থ এটি পরিবর্তন হয় না। উদাহরণ স্বরূপ:

final int CM_PER_INCH = 2.54;

আপনি পরিবর্তনশীল চূড়ান্ত ঘোষণা করবেন কারণ প্রতি ইঞ্চি সেন্টিমিটার পরিবর্তন হয় না।

যদি আপনি একটি চূড়ান্ত মান ওভাররাইড করার চেষ্টা করেন, চলকটি এটিই প্রথম ঘোষণা করা হয়েছিল। উদাহরণ স্বরূপ:

final String helloworld = "Hello World";
helloworld = "A String"; //helloworld still equals "Hello World"

একটি সংকলন ত্রুটি রয়েছে যা এরকম কিছু:

local variable is accessed from inner class, must be declared final

যদি আপনার পরিবর্তনশীল চূড়ান্ত হিসাবে ঘোষণা করা যায় না বা আপনি যদি এটি চূড়ান্ত ঘোষণা করতে না চান তবে চেষ্টা করুন:

final String[] helloworld = new String[1];
helloworld[0] = "Hello World!";
System.out.println(helloworld[0]);
helloworld[0] = "A String";
System.out.println(helloworld[0]);

এটি মুদ্রণ করবে:

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