জাভাতে "চূড়ান্ত" কীওয়ার্ডটি কীভাবে কাজ করে? (আমি এখনও কোনও বস্তু সংশোধন করতে পারি))


480

জাভাতে আমরা finalভেরিয়েবল সহ কীওয়ার্ড ব্যবহার করে এর মানগুলি পরিবর্তন করতে হয় না তা নির্দিষ্ট করে। তবে আমি দেখতে পাচ্ছি আপনি ক্লাসের কনস্ট্রাক্টর / পদ্ধতিতে মানটি পরিবর্তন করতে পারেন। আবার চলকটি যদি হয় staticতবে এটি সংকলন ত্রুটি।

কোডটি এখানে:

import java.util.ArrayList;
import java.util.List;

class Test {
  private final List foo;

  public Test()
  {
      foo = new ArrayList();
      foo.add("foo"); // Modification-1
  }
  public static void main(String[] args) 
  {
      Test t = new Test();
      t.foo.add("bar"); // Modification-2
      System.out.println("print - " + t.foo);
  }
}

উপরের কোডটি সূক্ষ্মভাবে কাজ করে এবং কোনও ত্রুটি নেই।

ভেরিয়েবলটি এখন এই হিসাবে পরিবর্তন করুন static:

private static final List foo;

এখন এটি একটি সংকলন ত্রুটি। এটি কীভাবে finalকাজ করে?


যেহেতু ফু দৃশ্যমান নয় - এটি কীভাবে সংকলন করতে পারে?
বিজরান হলস্ট্রোম

5
পছন্দ করেছেন প্রাইভেট স্ট্যাটিক ভেরিয়েবলগুলি বৈধ, তারা যে শ্রেণীর মধ্যে সংজ্ঞায়িত হয়েছে সেগুলির অভ্যন্তরে স্থির পদ্ধতিগুলি থেকে অ্যাক্সেসযোগ্য A একটি স্থির পরিবর্তনশীল এর অর্থ হল ভেরিয়েবলটি একবার উপস্থিত হয় এবং কোনও শ্রেণীর উদাহরণের সাথে আবদ্ধ হয় না।
এমবিডিভিস 10'15

3
@ এমএমডিভিস ওহ হ্যাঁ! ধন্যবাদ. তবে তবুও আমি আমার মতামত ভাবছে এমন লোকদের সহায়তা করতে মন্তব্যটি মুছে ফেলব না এবং তারপরে আপনার মন্তব্য তাদের সঠিক দিকে চিন্তা করতে বাধ্য করবে।
Therelprashant

@ সেখানে লালশান্ত ঠিক আছে কোন চিন্তা নেই!
এমবিডিভিস

উত্তর:


518

আপনি সবসময় একটি পরিবর্তনশীল আরম্ভ করার অনুমতি দেওয়া হয় final। সংকলকটি নিশ্চিত করে যে আপনি এটি একবারে করতে পারেন।

নোট করুন যে কোনও finalভেরিয়েবলে সঞ্চিত কোনও বস্তুর কল করার পদ্ধতিগুলির শব্দার্থক শব্দগুলির সাথে কোনও সম্পর্ক নেই final। অন্য কথায়: finalকেবলমাত্র রেফারেন্স সম্পর্কেই, এবং রেফারেন্স করা অবজেক্টের বিষয়বস্তু সম্পর্কে নয়।

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


12
চেষ্টা করুন t.foo = নতুন অ্যারেলিস্ট (); মূল পদ্ধতিতে এবং আপনি সংকলন ত্রুটিটি পাবেন ... রেফারেন্স
ফুটি অ্যারেলিস্টের

50
Hmmm। রেফারেন্স সম্পর্কে এটি সমস্ত মূল্য নয়। ধন্যবাদ!
জিএস

2
আমার একটা প্রশ্ন আছে. আমার পরিচিত কেউ দাবি করেছেন যে "চূড়ান্ত" দাবিটিও ভেরিয়েবলটিকে স্ট্যাকের মধ্যে সঞ্চয় করে তোলে। এটা কি সঠিক? আমি সর্বত্র অনুসন্ধান করেছি এবং এমন কোনও রেফারেন্স খুঁজে পাইনি যা এই দাবি অনুমোদিত বা অস্বীকার করতে পারে। আমি জাভা এবং অ্যান্ড্রয়েড উভয় ডকুমেন্টেশন অনুসন্ধান করেছি। "জাভা মেমরির মডেল" অনুসন্ধান করেছেন। হয়তো এটি সি / সি ++ এ এইভাবে কাজ করে তবে আমার মনে হয় না এটি জাভাতে এইভাবে কাজ করে। আমি কি সঠিক?
অ্যান্ড্রয়েড বিকাশকারী

4
@ অ্যান্ড্রয়েড ডেভেলপার জাভাতে কিছুই স্পষ্টভাবে স্ট্যাক / হিপ প্লেসমেন্ট নিয়ন্ত্রণ করতে পারে না। আরও সুনির্দিষ্টভাবে হটস্পট জেআইটি সংকলক কর্তৃক ঠিক করা স্ট্যাক প্লেসমেন্ট বিশ্লেষণের হাতছাড়া হওয়া , যা ভেরিয়েবল কিনা তা যাচাই করার চেয়ে অনেক বেশি জড়িত final। মিউটেবল অবজেক্টগুলি পাশাপাশি স্ট্যাক-বরাদ্দও করা যেতে পারে। finalক্ষেত্রগুলি পলায়ন বিশ্লেষণে সহায়তা করতে পারে, তবে এটি বেশ অপ্রত্যক্ষ পথ। এছাড়াও নোট করুন যে কার্যকরভাবে চূড়ান্ত ভেরিয়েবলগুলির finalউত্স কোডে চিহ্নিত হিসাবে একইরূপ আচরণ রয়েছে ।
মার্কো টপলনিক

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

574

এটি একটি প্রিয় সাক্ষাত্কারের প্রশ্ন । এই প্রশ্নগুলির সাথে, সাক্ষাত্কারকারক নির্মাতা, পদ্ধতি, শ্রেণি ভেরিয়েবল (স্ট্যাটিক ভেরিয়েবল) এবং দৃষ্টান্ত ভেরিয়েবলের ক্ষেত্রে অবজেক্টগুলির আচরণ সম্পর্কে আপনি কতটা ভাল বোঝেন তা জানার চেষ্টা করে।

import java.util.ArrayList;
import java.util.List;

class Test {
    private final List foo;

    public Test() {
        foo = new ArrayList();
        foo.add("foo"); // Modification-1
    }

    public void setFoo(List foo) {
       //this.foo = foo; Results in compile time error.
    }
}

উপরের ক্ষেত্রে, আমরা 'পরীক্ষার' জন্য একজন নির্ধারককে সংজ্ঞায়িত করেছি এবং এটিকে একটি 'সেটফু' পদ্ধতি দিয়েছি।

কন্সট্রাকটর সম্পর্কে: রচয়িতা শুধুমাত্র প্রার্থনা করা যেতে পারে এক ব্যবহার করে বস্তুর সৃষ্টি প্রতি সময় newশব্দ। আপনি একাধিকবার কনস্ট্রাক্টরকে আবেদন করতে পারবেন না, কারণ এটির জন্য কনস্ট্রাক্টর ডিজাইন করা হয়নি।

পদ্ধতি সম্পর্কে: কোনও পদ্ধতিটি আপনি চান যতবার ডাকা যেতে পারে (এমনকি কখনও নয়) এবং সংকলক এটি জানে it

দৃশ্যপট 1

private final List foo;  // 1

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

যদি আমরা fooকোনও পদ্ধতির অভ্যন্তরে অ্যাসাইন করি তবে সংকলকটি জানে যে কোনও পদ্ধতিটিকে একাধিকবার বলা যেতে পারে, যার অর্থ মানটি একাধিকবার পরিবর্তন করতে হবে, যা finalভেরিয়েবলের জন্য অনুমোদিত নয় । তাই সংকলক সিদ্ধান্ত নেয় কনস্ট্রাক্টর ভাল পছন্দ! আপনি কেবলমাত্র একবারে চূড়ান্ত ভেরিয়েবলের মান নির্ধারণ করতে পারেন।

দৃশ্য 2

private static final List foo = new ArrayList();

fooএখন একটি স্থির পরিবর্তনশীল। আমরা যখন Testক্লাসের উদাহরণ তৈরি করি তখন স্থিতিশীল fooহওয়ায় অবজেক্টে অনুলিপি করা হবে না foo। এখন fooপ্রতিটি বস্তুর স্বতন্ত্র সম্পত্তি নয়। এটি Testশ্রেণীর সম্পত্তি । তবে fooএকাধিক অবজেক্টের দ্বারা দেখা যায় এবং মূল newশব্দটি Testএকাধিক অবজেক্ট তৈরির সময় পরিবর্তনকারী কনস্ট্রাক্টরকে অনুরোধ করবে যা ব্যবহার করে তৈরি করা প্রতিটি বস্তু (মনে রাখবেন static fooপ্রতিটি বস্তুতে অনুলিপি করা হয় না, তবে একাধিক বস্তুর মধ্যে ভাগ করা হয়) ।)

পরিস্থিতি 3

t.foo.add("bar"); // Modification-2

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

চূড়ান্ত ক্লাসগুলি সাবক্ল্যাসড করা যায় না
চূড়ান্ত পদ্ধতিগুলি ওভাররাইড করা যায় না। (এই পদ্ধতিটি সুপারক্লাসে রয়েছে)
চূড়ান্ত পদ্ধতিগুলি ওভাররাইড করতে পারে। (ব্যাকরণগত পদ্ধতিতে এটি পড়ুন। এই পদ্ধতিটি একটি সাবক্লাসে রয়েছে)


1
শুধু পরিষ্কার হতে। পরিস্থিতি 2 এ আপনি কি বলছেন যে fooচূড়ান্ত পদবি থাকা সত্ত্বেও একাধিকবার সেট করা হবে যদি fooটেস্ট ক্লাসে সেট করা হয় এবং টেস্টের একাধিক উদাহরণ তৈরি হয়?
রাউর

দৃশ্য 2 এর শেষ লাইনটি বুঝতে পারি নি: তবে fooহতে পারে .. একাধিক বস্তু হতে পারে)) এর অর্থ কি, যদি আমি এক সাথে একাধিক অবজেক্ট তৈরি করি, তবে কোন বস্তুটি চূড়ান্ত পরিবর্তনশীল সূচনা করছে তা কার্যকর করার উপর নির্ভর করে?
সৌম্য সুহাগিয়া

1
আমি মনে করি সহায়ক পরিস্থিতি 3 সম্পর্কে ভাবার সহায়ক উপায়টি হ'ল আপনি যে অ্যারেলিস্টটি finalউল্লেখ করেছেন সেই মেমরি ঠিকানাকেই অর্পণ করছেন foo। আপনি finalমেমরি ঠিকানার প্রথম উপাদানটি foo(বা সেই বিষয়ে কোনও উপাদান) দ্বারা রেফারেন্স দিচ্ছেন না । অতএব আপনি পরিবর্তন করতে পারবেন না fooতবে পরিবর্তন করতে পারবেন foo[0]
পিঙ্কারটন

@ রাউর যেমন দাঁড়িয়েছে, পরিস্থিতি 2 এর কারণে একটি সংকলন-সময় ত্রুটি ঘটবে foo = new ArrayList();- fooস্থিতিশীল ভেরিয়েবলকে বোঝায় কারণ আমরা একই শ্রেণীর ভিতরে আছি।
ফ্লো 2 কে

আমি একটি সি ++ বিকাশকারী জাভা শিখছি। সি ++ এর কীওয়ার্ডের finalমতো একটি ভেরিয়েবলের বিষয়ে চিন্তা করা কি নিরাপদ const?
ডগ বারবিয়েরি

213

ফাইনাল কীওয়ার্ডটি ব্যবহারের অসংখ্য উপায় রয়েছে:

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

অন্যান্য ব্যবহার:

  • যখন কোনও বেনামে অভ্যন্তরীণ শ্রেণিটি কোনও পদ্ধতির শরীরে সংজ্ঞায়িত করা হয়, তখন সেই পদ্ধতির পরিধিতে চূড়ান্ত ঘোষিত সমস্ত পরিবর্তনগুলি অভ্যন্তরীণ শ্রেণীর মধ্যে থেকে অ্যাক্সেসযোগ্য হয়

জেভিএমের শুরু থেকে একটি স্ট্যাটিক ক্লাস ভেরিয়েবল উপস্থিত থাকবে এবং ক্লাসে আরম্ভ করা উচিত। আপনি এটি করলে ত্রুটি বার্তা উপস্থিত হবে না।


24
এটি এখন পর্যন্ত আমার প্রিয় উত্তর। সরল এবং সোজা-এগিয়ে, আমি জাভা সম্পর্কে অনলাইন ডক্সে এটি পড়তে আশা করি।
রেন্ডারস

স্ট্যাটিক ভেরিয়েবলগুলিতে আমরা যতবার চাই ইনিশিয়েল করতে পারি?
জোর্জে সরাইভা

1
@ জোরজেসারাইভা হ্যাঁ, স্ট্যাটিক ভেরিয়েবলগুলি ধ্রুবক নয়।
সিজাপে

1
@ জোরজেসারাইভা আপনি যতবার চান ক্ষেত্রগুলি (যতক্ষণ না তারা যতক্ষণ না ) বরাদ্দ করতে পারেন ( আরম্ভstatic নয় final) অ্যাসাইনমেন্ট এবং আরম্ভের মধ্যে পার্থক্যের জন্য এই উইকিটি দেখুন ।

56

দ্য finalশব্দ দুটি ভিন্ন উপর নির্ভর করে উপায়ে ব্যাখ্যা করা যেতে পারে তা ব্যবহার আছে:

মান ধরণের: এর জন্য int,double গুলি ইত্যাদি, এটা নিশ্চিত করবে যে মান পরিবর্তন করতে পারে না,

রেফারেন্সের প্রকারগুলি: অবজেক্টের রেফারেন্সের জন্য, রেফারেন্সটিfinal নিশ্চিত করে কখনই পরিবর্তিত হবে না, অর্থাত্ এটি সর্বদা একই বস্তুর করবে। এটি অবজেক্টের অভ্যন্তরের মানগুলি একই থাকাকে বোঝার কোনও নিশ্চয়তা দেয় না।

যেমনটি final List<Whatever> foo;নিশ্চিত করে যে fooসর্বদা একই তালিকাকে রেফার করে , তবে উল্লিখিত তালিকার বিষয়বস্তু সময়ের সাথে সাথে পরিবর্তন হতে পারে।


23

আপনি যদি fooঅচল করে থাকেন তবে আপনাকে অবশ্যই নীচের উদাহরণগুলির মতো ক্লাস কনস্ট্রাক্টর (অথবা ইনলাইন যেখানে আপনি এটি সংজ্ঞায়িত করবেন) তে শুরু করতে হবে।

শ্রেণি নির্মাতা (উদাহরণ নয়):

private static final List foo;

static
{
   foo = new ArrayList();
}

সঙ্গতিপূর্ণভাবে:

private static final List foo = new ArrayList();

এখানে সমস্যাটি কীভাবে finalসংশোধক কাজ করে তা নয়, পরিবর্তক কীভাবে কাজ করে তা নয় static

finalপরিবর্তক সময় করে আপনার কন্সট্রাকটর সম্পূর্ণ করেন কল (অর্থাত আপনি কন্সট্রাকটর এটা আরম্ভ আবশ্যক) আপনার অবগতির একজন আরম্ভের enforces।

আপনি যখন লাইনটিতে কোনও বৈশিষ্ট্য শুরু করেন, তখন আপনি কনস্ট্রাক্টরের জন্য সংজ্ঞায়িত কোডটি চালানোর আগেই তা আরম্ভ করা হয়, সুতরাং আপনি নিম্নলিখিত ফলাফলগুলি পান:

  • যদি fooহয় static, foo = new ArrayList()আগে মৃত্যুদন্ড কার্যকর করা হবে static{}কন্সট্রাকটর আপনি আপনার বর্গ জন্য সংজ্ঞায়িত করেছেন মৃত্যুদন্ড কার্যকর করা হয়
  • যদি fooনয় static, foo = new ArrayList()আগে আপনার কন্সট্রাকটর রান হয় মৃত্যুদন্ড কার্যকর করা হবে

আপনি যখন লাইনটিতে কোনও অ্যাট্রিবিউট শুরু করেন না, তখন পরিবর্তনকারী এটি finalপ্রয়োগ করে যে আপনি এটি আরম্ভ করেছেন এবং আপনাকে অবশ্যই কনস্ট্রাক্টরে এটি করতে হবে। আপনার যদি কোনও staticমডিফায়ারও থাকে, আপনি যে কন্সট্রাক্টরটিতে বৈশিষ্ট্যটি শুরু করতে হবে তা হ'ল ক্লাসের আরম্ভকরণ ব্লক:static{}

আপনি আপনার কোডটিতে যে ত্রুটিটি পেয়েছেন static{}তা ক্লাসটি লোড হওয়ার পরে চালিত হওয়ার ঘটনাটি থেকে ঘটেছিল, আপনি যখন class শ্রেণীর কোনও অবজেক্ট ইনস্ট্যান্ট করেন তার আগে। সুতরাং, fooক্লাসটি তৈরি হওয়ার সময় আপনি আরম্ভ করবেন না ।

static{}টাইপের কোনও অবজেক্টের জন্য ব্লককে কনস্ট্রাক্টর হিসাবে ভাবেন Class। এটি আপনার static finalশ্রেণীর বৈশিষ্ট্যগুলির সূচনা করতে হবে (যদি ইনলাইনটি না করে থাকে)।

সাইড নোট:

finalপরিবর্তক কেবল আদিম ধরণের এবং রেফারেন্সের জন্য কনস্ট-নেসকে আশ্বাস দেয়।

আপনি যখন কোনও finalবস্তু ঘোষণা করেন তখন যা পাবেন তা একটি final রেফারেন্স সেই বস্তুর , তবে অবজেক্টটি নিজেই ধ্রুবক নয়।

কোনও finalঅ্যাট্রিবিউট ঘোষণার সময় আপনি যা অর্জন করছেন তা হ'ল, একবার আপনি যখন আপনার নির্দিষ্ট উদ্দেশ্যে (যেমন final Listআপনি ঘোষণা করেছেন) কোনও বস্তু ঘোষণা করেন, কেবলমাত্র সেই অবজেক্টটি সেই উদ্দেশ্যে ব্যবহার করা হবে: আপনি এতে পরিবর্তন List fooকরতে পারবেন না অন্যটি List, তবে আপনি এখনও Listআইটেমগুলি যুক্ত / সরিয়ে নিজের পরিবর্তন করতে পারেন ( Listআপনি যেগুলি ব্যবহার করছেন সেটি একই হবে, কেবলমাত্র এর সামগ্রীগুলি পরিবর্তিত হবে)।


8

এটি একটি খুব ভাল সাক্ষাত্কার প্রশ্ন। কখনও কখনও তারা আপনাকে জিজ্ঞাসাও করতে পারে একটি চূড়ান্ত বস্তু এবং অপরিবর্তনীয় বস্তুর মধ্যে পার্থক্য কী।

1) যখন কেউ একটি চূড়ান্ত বস্তুর উল্লেখ করে, তার অর্থ হ'ল রেফারেন্সটি পরিবর্তন করা যায় না, তবে এর অবস্থার (উদাহরণের পরিবর্তনশীল) পরিবর্তন করা যায়।

2) একটি অপরিবর্তনীয় বস্তু হ'ল যার রাজ্য পরিবর্তন করা যায় না , তবে এর রেফারেন্স পরিবর্তন করা যায়। উদা:

    String x = new String("abc"); 
    x = "BCG";

রেফ ভেরিয়েবল এক্সকে আলাদা স্ট্রিং নির্দেশ করতে পরিবর্তন করা যেতে পারে, তবে "এবিসি" এর মান পরিবর্তন করা যায় না।

3) ইনস্ট্রাক্ট ভেরিয়েবলগুলি (নন স্ট্যাটিক ফিল্ড) আরম্ভ করা হয় যখন কোন কনস্ট্রাক্টর বলা হয়। সুতরাং আপনি কোনও কনস্ট্রাক্টরের অভ্যন্তরে আপনার ভেরিয়েবলের মানগুলি আরম্ভ করতে পারেন।

4) "তবে আমি দেখতে পাচ্ছি আপনি ক্লাসের কনস্ট্রাক্টর / পদ্ধতিতে মান পরিবর্তন করতে পারবেন"। - আপনি এটি কোনও পদ্ধতির অভ্যন্তরে পরিবর্তন করতে পারবেন না।

5) ক্লাস লোডিংয়ের সময় একটি স্ট্যাটিক ভেরিয়েবল শুরু করা হয়। সুতরাং আপনি কোনও কনস্ট্রাক্টরের ভিতরে আরম্ভ করতে পারবেন না, এটির আগেও এটি করতে হবে। সুতরাং আপনাকে ঘোষণার সময় স্ট্যাটিক ভেরিয়েবলের মানগুলি নির্ধারণ করতে হবে ।


7

finalজাভা শব্দ ব্যবহারকারী সীমাবদ্ধ করতে ব্যবহার করা হয়। জাভা finalকীওয়ার্ডটি অনেক প্রসঙ্গে ব্যবহার করা যেতে পারে। চূড়ান্ত হতে পারে:

  1. পরিবর্তনশীল
  2. পদ্ধতি
  3. শ্রেণী

finalকীওয়ার্ডটি ভেরিয়েবল সঙ্গে প্রয়োগ করা যেতে পারে একটি finalপরিবর্তনশীল কোন মূল্য আছে ফাঁকা বলা হয় finalপরিবর্তনশীল বা uninitialized finalপরিবর্তনশীল। এটি কেবল কনস্ট্রাক্টরেই শুরু করা যেতে পারে। ফাঁকা finalভেরিয়েবলটিও হতে পারে staticযা staticকেবলমাত্র ব্লকটিতে আরম্ভ করা হবে ।

জাভা চূড়ান্ত পরিবর্তনশীল:

যদি আপনি কোন পরিবর্তনশীল যেমন করেন তাহলে final, আপনি মান পরিবর্তন করতে পারবেন না এর finalপরিবর্তনশীল (এটা ধ্রুব থাকবে)।

finalপরিবর্তনশীল উদাহরণ

একটি চূড়ান্ত ভেরিয়েবল স্পিডলিট রয়েছে, আমরা এই ভেরিয়েবলের মান পরিবর্তন করতে যাচ্ছি, তবে এটি পরিবর্তন করা যাবে না কারণ চূড়ান্ত ভেরিয়েবল একবার নির্ধারিত মান কখনই পরিবর্তন করা যায় না।

class Bike9{  
    final int speedlimit=90;//final variable  
    void run(){  
        speedlimit=400;  // this will make error
    }  

    public static void main(String args[]){  
    Bike9 obj=new  Bike9();  
    obj.run();  
    }  
}//end of class  

জাভা ফাইনাল ক্লাস:

আপনি যদি এর মতো কোনও ক্লাস করেন তবে finalআপনি এটি বাড়িয়ে দিতে পারবেন না

চূড়ান্ত শ্রেণির উদাহরণ

final class Bike{}  

class Honda1 extends Bike{    //cannot inherit from final Bike,this will make error
  void run(){
      System.out.println("running safely with 100kmph");
   }  

  public static void main(String args[]){  
      Honda1 honda= new Honda();  
      honda.run();  
      }  
  }  

জাভা চূড়ান্ত পদ্ধতি:

আপনি যদি কোনও পদ্ধতি চূড়ান্ত হিসাবে করেন তবে আপনি এটিকে ওভাররাইড করতে পারবেন না

হোন্ডায় finalপদ্ধতির (রান () চালনার উদাহরণ (বাইকে চালানো ওভাররাইড করতে পারে না))

class Bike{  
  final void run(){System.out.println("running");}  
}  

class Honda extends Bike{  
   void run(){System.out.println("running safely with 100kmph");}  

   public static void main(String args[]){  
   Honda honda= new Honda();  
   honda.run();  
   }  
}  

ভাগ করেছেন: http://www.javatPoint.com/final-keyword


7

কিছু সরল সংজ্ঞা উল্লেখ করা মূল্যবান:

ক্লাস / পদ্ধতি

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

ভেরিয়েবল

একবার কোনও finalভেরিয়েবল শুরু হয়ে গেলে , এটিতে সর্বদা একই মান থাকে।

final মূলত কেসটির উপর নির্ভর করে কোনও কিছুই (উপশ্রেণী, ভেরিয়েবল "রিসাইন") দ্বারা ওভাররাইট / সুপারক্রাইপড এড়ান।


1
আমি ভেরিয়েবল সম্পর্কে চূড়ান্ত সংজ্ঞাটি কিছুটা সংক্ষিপ্ত বলে মনে করি; "জাভাতে, যখন চূড়ান্ত কীওয়ার্ডটি আদিম ডেটা টাইপের (ইন্ট, ফ্লোট, ইত্যাদি ইত্যাদি) এর সাথে ব্যবহার করা হয়, তখন ভেরিয়েবলের মান পরিবর্তন করা যায় না তবে অ-আদিম ভেরিয়েবলগুলির সাথে চূড়ান্ত যখন ব্যবহৃত হয় (দ্রষ্টব্য নন-আদিম ভেরিয়েবলগুলি জাভাতে সর্বদা অবজেক্টের রেফারেন্স হয়), রেফারেন্স করা অবজেক্টের সদস্যদের পরিবর্তন করা যেতে পারে। অ-আদিম ভেরিয়েবলের চূড়ান্ত অর্থ এই যে তারা অন্য কোনও বস্তুর রেফারেন্স হিসাবে পরিবর্তন করা যায় না "। geeksforgeeks.org/g-fact-48
সিইন

বৈধ, বিশেষত আদিম এবং অ-আদিম কেস হিসাবে উল্লেখ করার জন্য। Tks।
ivanleoncz

4

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

public static final String hello = "Hello";

যখন আমরা finalএকটি ভেরিয়েবল ডিক্লেয়ারেশন সহ কীওয়ার্ডটি ব্যবহার করি তখন সেই ভেরিয়েবলের অভ্যন্তরে সঞ্চিত মানটি পরে পরিবর্তন করা যায় না।

উদাহরণ স্বরূপ:

public class ClassDemo {
  private final int var1 = 3;
  public ClassDemo() {
    ...
  }
}

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

চূড়ান্ত কীওয়ার্ড ব্যবহারের সুবিধাগুলি এই থ্রেডে সম্বোধন করা হয়েছে


2
the value stored inside that variable cannot be changed latterআংশিক সত্য। এটি শুধুমাত্র আদিম ডেটা ধরণের জন্য সত্য। কোনও বস্তুর ক্ষেত্রে finalঅ্যারেলিস্টের মতো তৈরি করা হলেও এর মান পরিবর্তন হতে পারে তবে রেফারেন্স নয় not ধন্যবাদ!
জিএস

3

ধরুন আপনার কাছে লাল এবং সাদা দুটি মানিবক্স রয়েছে। আপনি এই মানিবক্সগুলি কেবলমাত্র দুটি শিশুকে অর্পণ করেন এবং তাদের বাক্সগুলি বিনিময় করার অনুমতি নেই। সুতরাং আপনার কাছে লাল বা সাদা মানিবক্স রয়েছে (চূড়ান্ত) আপনি বাক্সটি সংশোধন করতে পারবেন না তবে আপনি আপনার বাক্সে অর্থ রাখতে পারেন obNobody cares (পরিবর্তন -২)।


2

সমস্ত উত্তর পড়ুন।

আরও একটি ব্যবহারকারীর ক্ষেত্রে রয়েছে যেখানে finalকীওয়ার্ডটি ব্যবহার করা যেতে পারে অর্থাত্ একটি পদ্ধতিতে:

public void showCaseFinalArgumentVariable(final int someFinalInt){

   someFinalInt = 9; // won't compile as the argument is final

}

পরিবর্তনশীল জন্য ব্যবহার করা যেতে পারে যা পরিবর্তন করা উচিত নয়।


1

আপনি যখন এটি স্থির চূড়ান্ত করেন এটি একটি স্ট্যাটিক ইনিশিয়ালাইজেশন ব্লকে শুরু করা উচিত

    private static final List foo;

    static {
        foo = new ArrayList();
    }

    public Test()
    {
//      foo = new ArrayList();
        foo.add("foo"); // Modification-1
    }

1

finalশব্দ নির্দেশ করে যে একটি পরিবর্তনশীল শুধুমাত্র একবার সক্রিয়া করা যেতে পারে। আপনার কোডে আপনি কেবলমাত্র ফাইনালের একটি সূচনা করছেন যাতে শর্তাদি সন্তুষ্ট হয়। এই বিবৃতিটির একাকীকরণ শুরু করে foo। নোট করুন final! = পরিবর্তনযোগ্য, এর অর্থ কেবলমাত্র রেফারেন্স পরিবর্তন হতে পারে না change

foo = new ArrayList();

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

আপনি যখন আপনার পদ্ধতিটি কার্যকর করেন static final দৃশ্যেরTest ক্লাসটি ইনস্ট্যান্ট tকরার আগে লোড করা হয় যখন fooঅর্থের কোনও ইনস্ট্যান্টেশন নেই এটি আরম্ভ করা হয়নি তাই fooএটি সমস্ত বস্তুর জন্য ডিফল্ট হিসাবে সেট করা আছে nullNullPointerExceptionআপনি যখন তালিকায় কোনও আইটেম যুক্ত করার চেষ্টা করবেন তখন এই মুহুর্তে আমি আপনার কোডটি একটি ছুড়ে ফেলেছি বলে মনে করি ।


1

প্রথমত, আপনার কোডের যে জায়গাটি আপনি শুরু করছেন (যেমন প্রথমবারের জন্য নির্ধারণ করছেন) foo এখানে রয়েছে:

foo = new ArrayList();

foo হ'ল একটি অবজেক্ট (টাইপ লিস্ট সহ) তাই এটি একটি রেফারেন্স টাইপ, কোনও মান টাইপ নয় (int এর মতো)। যেমন, এটি একটি মেমরি অবস্থানের (যেমন 0xA7D2A834) যেখানে আপনার তালিকার উপাদানগুলি সঞ্চিত আছে তার রেফারেন্স ধারণ করে। লাইনের মতো

foo.add("foo"); // Modification-1

foo এর মান পরিবর্তন করবেন না (যা আবার, একটি মেমরির অবস্থানের কেবল উল্লেখ)। পরিবর্তে, তারা কেবল সেই রেফারেন্সযুক্ত মেমরির স্থানে উপাদান যুক্ত করে। চূড়ান্ত কীওয়ার্ড লঙ্ঘন করতে আপনাকে নীচে নীচে আবার ফু-নিয়োগের চেষ্টা করতে হবে:

foo = new ArrayList();

যে হবে আপনি যদি একটি সংকলন ত্রুটি দেব।


এখন, উপায়টি অতিক্রম করে, আপনি যখন স্ট্যাটিক কীওয়ার্ডটি যুক্ত করেন তখন কী ঘটে তা ভেবে দেখুন ।

যখন আপনার কাছে স্থিতিশীল কীওয়ার্ড না থাকে, ক্লাসটি ইনস্ট্যান্ট করে দেয় এমন প্রতিটি বস্তুর নিজের ফু এর অনুলিপি থাকে। অতএব, কনস্ট্রাক্টর foo ভেরিয়েবলের একটি ফাঁকা, নতুন কপিতে একটি মান নির্ধারণ করে, যা পুরোপুরি ঠিক আছে।

যাইহোক, যখন আপনার স্থির কীওয়ার্ড থাকে তখন ক্লাসের সাথে সম্পর্কিত মেমরিতে কেবল একটি ফু থাকে। আপনি যদি দুটি বা ততোধিক অবজেক্ট তৈরি করতে চান তবে কনস্ট্রাক্টর চূড়ান্ত কীওয়ার্ড লঙ্ঘন করে প্রতিবার সেই একটি ফুকে পুনরায় বরাদ্দ দেওয়ার চেষ্টা করবে ।


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

1

নীচে বিভিন্ন প্রসঙ্গ রয়েছে যেখানে চূড়ান্ত ব্যবহার করা হয়।

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

class Main {
   public static void main(String args[]){
      final int i = 20;
      i = 30; //Compiler Error:cannot assign a value to final variable i twice
   }
}

চূড়ান্ত ভেরিয়েবলটি পরে মান নির্ধারণ করা যেতে পারে (ঘোষণার সময় নির্ধারিত কোনও মান বাধ্যতামূলক নয়), তবে কেবল একবার।

ফাইনাল ক্লাস একটি ফাইনাল ক্লাস বাড়ানো যায় না (উত্তরাধিকারসূত্রে)

final class Base { }
class Derived extends Base { } //Compiler Error:cannot inherit from final Base

public class Main {
   public static void main(String args[]) {
   }
}

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

//Error in following program as we are trying to override a final method.
class Base {
  public final void show() {
       System.out.println("Base::show() called");
    }
}     
class Derived extends Base {
    public void show() {  //Compiler Error: show() in Derived cannot override
       System.out.println("Derived::show() called");
    }
}     
public class Main {
    public static void main(String[] args) {
        Base b = new Derived();;
        b.show();
    }
}

1

আমি এখানে একটি আপডেট এবং গভীর উত্তর লিখতে ভেবেছিলাম।

final কীওয়ার্ডটি বেশ কয়েকটি জায়গায় ব্যবহার করা যেতে পারে।

  1. ক্লাস

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

উদা:

F myF;
myF = new F();    //ok
myF = someOther;  //someOther cannot be in type of a child class of F.
                  //because F cannot be extended.

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

  1. পদ্ধতি

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

  1. ক্ষেত্র, স্থানীয় ভেরিয়েবল, পদ্ধতি পরামিতি

যদি উপরের কোনও প্রকার যেমন নির্দিষ্ট করা থাকে final, তার অর্থ হল ইতিমধ্যে মানটি চূড়ান্ত হয়ে গেছে, সুতরাং মানটি পরিবর্তন করা যায় না

উদা:

ক্ষেত্রগুলির জন্য, স্থানীয় পরামিতি

final FinalClass fc = someFC; //need to assign straight away. otherwise compile error.
final FinalClass fc; //compile error, need assignment (initialization inside a constructor Ok, constructor can be called only once)
final FinalClass fc = new FinalClass(); //ok
fc = someOtherFC; //compile error
fc.someMethod(); //no problem
someOtherFC.someMethod(); //no problem

পদ্ধতির পরামিতিগুলির জন্য

void someMethod(final String s){
    s = someOtherString; //compile error
}

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

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


0

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

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