জাভাতে কোনও পদ্ধতি প্যারামিটারে আমি কেন "চূড়ান্ত" শব্দটি ব্যবহার করব?


381

finalকীওয়ার্ডটি যখন পদ্ধতি পরামিতিগুলিতে ব্যবহৃত হয় তখন সত্যই কার্যকর হয় না আমি বুঝতে পারি না ।

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

কিছু ডেটা স্থির থাকে তা প্রয়োগ করা ততটা শক্তিশালী নয়।

  • যদি প্যারামিটারটি কোনও আদিম হয় তবে প্যারামিটারটি মান হিসাবে পদ্ধতিতে পাস হওয়ার পরে এর কোনও প্রভাব পড়বে না এবং পরিবর্তিত হওয়ার ক্ষেত্রে সুযোগের বাইরে কোনও প্রভাব থাকবে না।

  • যদি আমরা রেফারেন্স দ্বারা কোনও প্যারামিটারটি পাস করি, তবে রেফারেন্সটি নিজেই একটি স্থানীয় ভেরিয়েবল এবং যদি পদ্ধতিটির মধ্যে থেকে রেফারেন্সটি পরিবর্তন করা হয় তবে এটি পদ্ধতির ক্ষেত্রের বাইরে থেকে কোনও প্রভাব ফেলবে না।

নীচের সহজ পরীক্ষার উদাহরণ বিবেচনা করুন। পদ্ধতিটি প্রদত্ত রেফারেন্সের মান পরিবর্তন করে যদিও এই পরীক্ষাটি পাস করে, এর কোনও প্রভাব নেই।

public void testNullify() {
    Collection<Integer> c  = new ArrayList<Integer>();      
    nullify(c);
    assertNotNull(c);       
    final Collection<Integer> c1 = c;
    assertTrue(c1.equals(c));
    change(c);
    assertTrue(c1.equals(c));
}

private void change(Collection<Integer> c) {
    c = new ArrayList<Integer>();
}

public void nullify(Collection<?> t) {
    t = null;
}

101
পরিভাষায় একটি দ্রুত পয়েন্ট - জাভাতে পাস-বাই-রেফারেন্স মোটেই নেই। এটিতে মান অনুসারে পাসের রেফারেন্স রয়েছে যা একই জিনিস নয়। রেফারেন্স শব্দার্থ মাধ্যমে সত্য পাসের সাথে আপনার কোডের ফলাফল আলাদা হবে।
জন স্কিটি

6
রেফারেন্স দ্বারা পাস এবং মান অনুসারে রেফারেন্সের মধ্যে পার্থক্য কী?
NobleUplift

এই পার্থক্যটিকে সি প্রসঙ্গে (কমপক্ষে আমার জন্য) বর্ণনা করা সহজ। আমি যদি কোনও পয়েন্টার যেমন: <code> int foo (int বার) </code>- তে কোনও পয়েন্টারটি পাস করি তবে সেই পয়েন্টারটি মান দ্বারা পাস হচ্ছে। অর্থ এটি অনুলিপি করা হয়েছে, সুতরাং আমি যদি এই পদ্ধতির ভিতরে <কোড> ফ্রি (বার) এর মতো কিছু করি; বার = malloc (...); </code> তবে আমি সবেমাত্র খুব খারাপ কাজ করেছি। ফ্রি কলটি প্রকৃতপক্ষে স্মৃতিশক্তির অবকাশকে মুক্ত করে দেবে (সুতরাং আমি যেই পয়েন্টারটি দিয়েছি তা এখন ঝুঁকছে)। যাইহোক, <code> int foo (int & bar) </bar> এর অর্থ কোডটি বৈধ এবং এতে পাসের পয়েন্টারের মান পরিবর্তন করা হবে।
জারস্লান

1
প্রথমটি হবার কথা int foo(int* bar)এবং শেষটি int foo(int* &bar)। পরেরটি রেফারেন্স দ্বারা একটি পয়েন্টারটি পার করছে, প্রাক্তনটি মান দ্বারা রেফারেন্সটি পার করছে।
জারস্লান

2
@ মার্টিন, আমার মতে এটি একটি ভাল প্রশ্ন ; প্রশ্নটির শিরোনাম এবং কেন প্রশ্ন জিজ্ঞাসা করা হয়েছে তার ব্যাখ্যা হিসাবে পোস্টের সামগ্রী দেখুন । সম্ভবত আমি এখানে নিয়মগুলি ভুল বুঝছি, তবে "পদ্ধতিতে চূড়ান্ত পরামিতিগুলির ব্যবহার" অনুসন্ধান করার সময় এটিই ঠিক আমি চাইছিলাম ।
ভিক্টর জামানমিয়ান

উত্তর:


239

একটি ভেরিয়েবলের পুনরায় নিয়োগ বন্ধ করুন

যদিও এই উত্তরগুলি বৌদ্ধিকভাবে আকর্ষণীয়, তবে আমি ছোট সরল উত্তরটি পড়িনি:

কোনও ভেরিয়েবলকে অন্য কোনও অবজেক্টকে পুনরায় বরাদ্দ দেওয়া থেকে বিরত রাখতে সংকলকটি চাইলে কীওয়ার্ড ফাইনালটি ব্যবহার করুন ।

ভেরিয়েবল একটি স্ট্যাটিক ভেরিয়েবল, সদস্য ভেরিয়েবল, স্থানীয় পরিবর্তনশীল, বা আর্গুমেন্ট / পরামিতি ভেরিয়েবল কিনা, প্রভাব পুরোপুরি একই is

উদাহরণ

কর্মের প্রভাবটি দেখুন।

এই সহজ পদ্ধতিটি বিবেচনা করুন, যেখানে দুটি ভেরিয়েবল ( আরগ এবং এক্স ) উভয়কেই ভিন্ন ভিন্ন বস্তু পুনরায় বরাদ্দ করা যেতে পারে।

// Example use of this method: 
//   this.doSomething( "tiger" );
void doSomething( String arg ) {
  String x = arg;   // Both variables now point to the same String object.
  x = "elephant";   // This variable now points to a different String object.
  arg = "giraffe";  // Ditto. Now neither variable points to the original passed String.
}

স্থানীয় পরিবর্তনশীলকে চূড়ান্ত হিসাবে চিহ্নিত করুন । এটি একটি সংকলক ত্রুটির ফলস্বরূপ।

void doSomething( String arg ) {
  final String x = arg;  // Mark variable as 'final'.
  x = "elephant";  // Compiler error: The final local variable x cannot be assigned. 
  arg = "giraffe";  
}

পরিবর্তে, আসুন পরামিতি ভেরিয়েবলটিকে চূড়ান্ত হিসাবে চিহ্নিত করি । এটিও একটি সংকলক ত্রুটির ফলস্বরূপ।

void doSomething( final String arg ) {  // Mark argument as 'final'.
  String x = arg;   
  x = "elephant"; 
  arg = "giraffe";  // Compiler error: The passed argument variable arg cannot be re-assigned to another object.
}

গল্পের শিক্ষা:

আপনি যদি কোনও ভেরিয়েবলটি সর্বদা একই বস্তুর দিকে নির্দেশ করতে চান তা নিশ্চিত করতে চান তবে ভেরিয়েবলটি ফাইনাল হিসাবে চিহ্নিত করুন ।

আর্গুমেন্ট পুনরায় নিযুক্ত করুন

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

রেট্রোস্পেক্টে

যেমন অন্যান্য উত্তরে উল্লিখিত হয়েছে… প্রোগ্রামারদের যেমন অ্যারের শেষের আগে পড়ার মতো বোবা ভুলগুলি এড়াতে সহায়তা করার জাভাটির মূল নকশা লক্ষ্যটি দেওয়া হয়েছে, জাভা সমস্ত প্যারামিটার / আর্গুমেন্ট ভেরিয়েবলগুলি স্বয়ংক্রিয়ভাবে 'চূড়ান্ত' হিসাবে প্রয়োগ করার জন্য তৈরি করা উচিত। অন্য কথায়, আর্গুমেন্টগুলি পরিবর্তনশীল হওয়া উচিত নয় । তবে হ্যান্ডসাইট 20/20 দৃষ্টিভঙ্গি এবং জাভা ডিজাইনারদের হাতে পুরো সময় ছিল।

সুতরাং, সবসময় finalসমস্ত যুক্তি যুক্ত করবেন?

আমাদের finalপ্রতিটি পদ্ধতির পরামিতি ঘোষিত হওয়াতে যুক্ত করা উচিত?

  • তত্ত্বগতভাবে, হ্যাঁ
  • অনুশীলনে, না।
    Only finalকেবলমাত্র পদ্ধতির কোডটি দীর্ঘ বা জটিল হলে যুক্ত করুন, যেখানে স্থানীয় বা সদস্য ভেরিয়েবলের জন্য যুক্তিটি ভুল হতে পারে এবং সম্ভবত পুনরায় বরাদ্দ করা যেতে পারে।

আপনি যদি কোনও যুক্তি পুনরায় বরাদ্দ না করার অভ্যাসটি ক্রয় করেন তবে finalআপনি প্রতিটিটিতে একটি যুক্ত করতে ঝুঁকবেন। তবে এটি ক্লান্তিকর এবং ঘোষণাটি পড়ার জন্য কিছুটা কঠিন করে তোলে।

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

সম্পূর্ণতার জন্য আরও একটি মামলা যুক্ত হয়েছিল

public class MyClass {
    private int x;
    //getters and setters
}

void doSomething( final MyClass arg ) {  // Mark argument as 'final'.

   arg =  new MyClass();  // Compiler error: The passed argument variable arg  cannot be re-assigned to another object.

   arg.setX(20); // allowed
  // We can re-assign properties of argument which is marked as final
 }

23
"ভাল প্রোগ্রামিং অনুশীলন হিসাবে (যে কোনও ভাষায়), আপনাকে কখনই কোনও প্যারামিটার / আর্গুমেন্ট ভেরিয়েবল পুনরায় বরাদ্দ করা উচিত নয় [..]" দুঃখিত, সত্যিই আমি আপনাকে এইটির জন্য ডেকে আছি। পুনরায় নির্ধারিত যুক্তি জাভাস্ক্রিপ্টের মতো ভাষায় স্ট্যান্ডার্ড অনুশীলন, যেখানে আর্গুমেন্টের পরিমাণটি পাস (বা কোনও পাস হলেও) পদ্ধতি স্বাক্ষরের দ্বারা নির্ধারিত হয় না। উদাহরণস্বরূপ একটি স্বাক্ষর দেওয়া হয়েছে: "ফাংশন বলুন (msg)" লোকেরা নিশ্চিত করবে যে যুক্তি '#' নির্ধারিত হয়েছে, এর মতো: "msg = msg || 'হ্যালো ওয়ার্ল্ড!';"। বিশ্বের সেরা জাভাস্ক্রিপ্ট প্রোগ্রামাররা আপনার ভাল অনুশীলনটি ভঙ্গ করছে। শুধু jQuery উত্স পড়ুন।
স্টিজন ডি উইট

37
@ স্টিজেডেভিট আপনার উদাহরণটি আর্গুমেন্ট ভেরিয়েবলটিকে পুনরায় নিয়োগের খুব সমস্যা দেখায়। বিনিময়ে প্রাপ্ত কোনও কিছুর সাথে আপনি তথ্য হারাবেন : (ক) আপনি মূল মূল্যটি হারিয়েছেন, (খ) আপনি কলিং পদ্ধতির অভিপ্রায়টি হারিয়ে ফেলেছেন (কলার 'হ্যালো ওয়ার্ল্ড পাস করেছেন নাকি আমরা ডিফল্ট হয়েছিল)'। A & B উভয়ই পরীক্ষার জন্য, লম্বা কোডের জন্য এবং যখন পরে আরও মান পরিবর্তন করা হয় তখন দরকারী। আমি আমার বক্তব্যকে সমর্থন করছি: আরগ ওয়ার্সগুলি কখনই পুনরায় নিয়োগ দেওয়া উচিত নয় । আপনার কোড হওয়া উচিত: message = ( msg || 'Hello World"' )। পৃথক ভার ব্যবহার না করার সহজ কারণ নেই । একমাত্র ব্যয় মেমরির কয়েক বাইট।
বাসিল বাউরক

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

14
ব্যবহার message = ( msg || 'Hello World"' )ঝুঁকি আমাকে পরে ঘটনাক্রমে ব্যবহার msg। যখন আমি চুক্তিটি করতে চাইছি "নোংরা / অপরিজ্ঞাত আর্গের সাথে আচরণটি পাশ করা থেকে পৃথক পৃথক "Hello World"", তখন ফাংশনের শুরুতে এটি প্রতিশ্রুতিবদ্ধ করার জন্য এটি একটি ভাল প্রোগ্রামিং অনুশীলন। [এটি শুরু করে পুনরায় নিয়োগ ছাড়াই অর্জন করা যেতে পারে if (!msg) return myfunc("Hello World");তবে এটি একাধিক যুক্তি দিয়ে অকার্যকর হয়ে পড়ে]] বিরল ক্ষেত্রে যেখানে ফাংশনের যুক্তিটি ডিফল্টটি ব্যবহৃত হয়েছিল কিনা সেদিকে খেয়াল রাখতে হবে, আমি বরং একটি বিশেষ সেন্ডিনেল মান নির্ধারণ করব (পছন্দসইভাবে প্রকাশ্য) ।
বেনি চেরনিয়াভস্কি-পাসকিন

6
@ BeniCherniavsky-Paskin ঝুঁকি আপনি বর্ণনা শুধুমাত্র মধ্যে মিল জন্যই messageএবং msg। তবে যদি তিনি এটিকে এমন কিছু processedMsgবা অতিরিক্ত প্রসঙ্গ সরবরাহ করে এমন কিছু বলে থাকেন - তবে ভুল হওয়ার সম্ভাবনা অনেক কম। তিনি কীভাবে "কীভাবে" বলেন না সেটির দিকে মনোনিবেশ করুন । ;)
আলফাসিন

230

কখনও কখনও এটি স্পষ্টভাবে (পঠনযোগ্যতার জন্য) ভাল লাগে যে পরিবর্তনশীল পরিবর্তন হয় না। এখানে একটি সাধারণ উদাহরণ যেখানে ব্যবহার করা finalকিছু সম্ভাব্য মাথাব্যথা বাঁচাতে পারে:

public void setTest(String test) {
    test = test;
}

যদি আপনি কোনও সেটারে 'এই' কীওয়ার্ডটি ভুলে যান তবে আপনি যে ভেরিয়েবলটি সেট করতে চান সেটি সেট হয় না। তবে, আপনি যদি finalপ্যারামিটারে কীওয়ার্ডটি ব্যবহার করেন , তবে সংকলনের সময় বাগটি ধরা পড়বে।


65
বিটিডব্লিউ আপনি সতর্কতা দেখতে পাবেন "ভেরিয়েবল টেস্টে নিয়োগের কোনও প্রভাব নেই"
এভ্রড্রাগন

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

10
@ অ্যাভ্রাড্রেগন এটি উন্নয়নের পরিবেশের উপর নির্ভরশীল। আপনি খারাপ অভ্যাস গড়ে তুলতে না চাইলে আপনার পক্ষে যাইহোক, আপনার জন্য এই জাতীয় জিনিসগুলি ধরার জন্য আইডিই'র উপর নির্ভর করা উচিত নয়।
b1nary.atr0phy

25
@ b1naryatr0phy আসলে এটি একটি সংকলক সতর্কতা, কেবল আইডিই-টিপ নয়
এভ্রড্রাগন

8
@ সুমিতডেসাই "তবে, আমরা সতর্কবার্তাটিকেও এড়িয়ে যেতে পারি। সুতরাং, সংকলনের ত্রুটির মতো আমাদের আরও এগিয়ে যাওয়া থেকে বিরত রাখতে পারে এমন কিছু পাওয়া সর্বদা ভাল, যা আমরা চূড়ান্ত কীওয়ার্ড ব্যবহার করে পেয়ে যাব।" আমি আপনার বক্তব্য গ্রহণ করি তবে এটি একটি অত্যন্ত দৃ statement় বক্তব্য যা আমার ধারণা অনেক জাভা বিকাশকারী একমত নন। সংকলক সতর্কতাগুলি একটি কারণে রয়েছে এবং একজন সক্ষম বিকাশকারীকে এর প্রভাবগুলি বিবেচনা করতে তাদের 'জোর' করতে কোনও ত্রুটির প্রয়োজন হবে না।
স্টুয়ার্ট রোসিটার

127

হ্যাঁ, বেনামে বর্গ, পাঠযোগ্যতা এবং উদ্দেশ্য ঘোষণাকে বাদ দিয়ে এটি প্রায় মূল্যহীন। এই তিনটি জিনিস কি মূল্যহীন?

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

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

সম্পাদনা: মন্টি পাইথন রেফারেন্স সহ আমার সত্যিই এই সমস্ত সংক্ষিপ্ত হওয়া উচিত ছিল; প্রশ্নটি জিজ্ঞাসার সাথে কিছুটা মিল বলে মনে হচ্ছে "রোমানরা আমাদের জন্য কি করেছে?"


17
তবে ক্রুস্টিকে তাঁর ডেনিশ দিয়ে প্যারাফ্রেস করতে, তারা কীভাবে আমাদের জন্য লেটলি করেছে ? =)
জেমস শেক

ইউভাল। মজার! আমার ধারণা, তরোয়াল ফলক প্রয়োগ করা হলেও শান্তি হতে পারে!
গঞ্জোব্রাইনগুলি

1
প্রশ্ন আরও জিজ্ঞাসা অনুরূপ বলে মনে হয়, "কি করেন নি রোমানদের আমাদের জন্য কাজ?", এটি চূড়ান্ত শব্দ কি একটি সমালোচনামূলক প্রবন্ধ আরো কারণ নেই না।
NobleUplift

"আপনি কি পরামর্শ দিচ্ছেন যে বিকাশকারীদের একটি উল্লেখযোগ্য সংস্থা রয়েছে যা সুপারিশ করে যে চূড়ান্তভাবে এটির চেয়ে বেশি প্রভাব রয়েছে?" আমার কাছে এটিই প্রধান সমস্যা: আমি বিকাশকারীদের একটি উল্লেখযোগ্য অনুপাত ব্যবহার করে দৃ strongly়ভাবে সন্দেহ করি যে এটির মাধ্যমে এটি কলারের পাস হওয়া আইটেমগুলির অপরিবর্তনীয়তা প্রয়োগ করে think অবশ্যই, তারপরে কেউ কোডিং মানকে ধারণাগত ভুল বোঝাবুঝির বিরুদ্ধে "রক্ষা করা উচিত" (যা একটি 'সক্ষম' বিকাশকারী সম্পর্কে সচেতন হওয়া উচিত) কিনা তা নিয়ে বিতর্কে ডুবে যায় এবং না (এবং এরপরে এটি একটি বহির্মুখী-মতামতের দিকে এগিয়ে যায়) টাইপ প্রশ্ন)!
স্টুয়ার্ট রোসিটার

1
@ সার্থক মিত্তাল: আপনি যদি ভাবছেন তবে এটির সত্যতা যদি আপনি এটি ব্যবহার না করেন তবে অনুলিপি করা হবে না।
জন স্কিটি

76

আপনার চূড়ান্ত ব্যবহার করতে হবে এমন একটি মামলার বিষয়ে আমাকে কিছুটা ব্যাখ্যা করতে দিন , যা জোন ইতিমধ্যে উল্লেখ করেছে:

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

public Iterator<Integer> createIntegerIterator(final int from, final int to)
{
    return new Iterator<Integer>(){
        int index = from;
        public Integer next()
        {
            return index++;
        }
        public boolean hasNext()
        {
            return index <= to;
        }
        // remove method omitted
    };
}

এখানে fromএবং toপরামিতিগুলি চূড়ান্ত হওয়া দরকার যাতে তারা বেনাম শ্রেণীর ভিতরে ব্যবহার করতে পারে।

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

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


1
আপনি আমাকে "তবে তারা চূড়ান্ত না হলে ...." থেকে হারিয়েছেন আপনি কি এটিকে পুনর্বিবেচনার চেষ্টা করতে পারেন, সম্ভবত আমার কাছে পর্যাপ্ত কফি নেই।
হাফেজ

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

এটি কোনও অনুলিপি তৈরি করে না, যা কিছু বস্তুর রেফারেন্স হয়েছিল তা কেবল এটির একটি রেফারেন্স।
বিকির্ক

1
@ উইকির্ক: রেফারেন্সের ধরণের ক্ষেত্রে এটি অবশ্যই একটি অনুলিপি তৈরি করেছে - রেফারেন্সের।
মাইকেল বর্গওয়ার্ট

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

25

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

এটি কি এত যোগ করে? আসলে তা না.

আমি কি এটি বন্ধ করব? না।

কারণ: আমি 3 টি বাগ খুঁজে পেয়েছি যেখানে লোকেরা slালু কোড লিখেছিল এবং অ্যাক্সেসরগুলিতে সদস্য ভেরিয়েবল সেট করতে ব্যর্থ হয়েছিল। সমস্ত বাগ খুঁজে পাওয়া কঠিন প্রমাণিত।

আমি জাভা এর ভবিষ্যতের সংস্করণে এটি ডিফল্ট হওয়া দেখতে চাই। মান / রেফারেন্স জিনিস দ্বারা পাস জুনিয়র প্রোগ্রামারদের একটি ভয়ঙ্কর প্রচুর পরিমাণে ট্রিপস।

আরও একটি বিষয় .. আমার পদ্ধতিগুলির প্যারামিটারের সংখ্যা কম থাকে তাই কোনও পদ্ধতি ঘোষণায় অতিরিক্ত পাঠ্য কোনও সমস্যা নয়।


4
আমি এটিও পরামর্শ দিতে চলেছিলাম, ভবিষ্যতের সংস্করণগুলিতে সেই চূড়ান্তটি ডিফল্ট হবে এবং আপনাকে "পরিবর্তনীয়" বা আরও ভাল কীওয়ার্ড নির্দিষ্ট করতে হবে যা ধারণা করা হয়েছে। এই সম্পর্কে একটি চমৎকার নিবন্ধ এখানে: lpar.ath0.com/2008/08/26/java-annoyance-final-paraters
জেফ অ্যাক্সেলরড

এটি অনেক দিন হয়ে গেছে, তবে আপনি যে বাগটি ধরেছিলেন তার উদাহরণ সরবরাহ করতে পারেন?
user949300

উত্তরের জন্য সর্বাধিক ভোট দেখুন। এটিতে একটি দুর্দান্ত উদাহরণ রয়েছে যেখানে সদস্য ভেরিয়েবল সেট করা থাকে না এবং পরিবর্তে প্যারামিটারটি পরিবর্তিত হয়।
ফরটিআরুনার

18

একটি পদ্ধতি প্যারামিটারে চূড়ান্ত ব্যবহারের সাথে কলারের পক্ষের তর্কটির সাথে কোনও সম্পর্ক নেই। এটি কেবলমাত্র সেই পদ্ধতির অভ্যন্তরে পরিবর্তন না হিসাবে চিহ্নিত করা to আমি আরও কার্যকরী প্রোগ্রামিং শৈলী অবলম্বন করার চেষ্টা করার সাথে সাথে আমি এর মধ্যে মূল্যটি দেখতে পাই।


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

8

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

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

আমি অবশ্যই সি / সি ++ কনস্টের মতো শক্তিশালী কিছু চাই।


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

4

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


1

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

private String getString(String A, int i, String B, String C)
{
    if (i > 0)
        A += B;

    if (i > 100)
        A += C;

    return A;
}

শয়তানের উকিল বাজানো, এটি করাতে ঠিক কী ভুল?


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

1

সংক্ষিপ্ত উত্তর: finalএকটি সামান্য বিট সাহায্য করে কিন্তু ... পরিবর্তে ক্লায়েন্ট পক্ষ থেকে প্রতিরক্ষা প্রোগ্রামিং ব্যবহার করুন।

প্রকৃতপক্ষে, সমস্যাটি finalহ'ল এটি কেবলমাত্র রেফারেন্সটি অপরিবর্তিতভাবে প্রয়োগ করে , আনন্দের সাথে রেফারেন্সযুক্ত অবজেক্ট সদস্যদের পরিবর্তন করতে, কলারের অজানা be সুতরাং এ বিষয়ে সর্বোত্তম অনুশীলন হ'ল আহ্বানকারী পক্ষের প্রতিরক্ষামূলক প্রোগ্রামিং, গভীরভাবে অবিচ্ছেদ্য ঘটনাগুলি বা অনুলিপিযুক্ত API গুলি দ্বারা জড়িয়ে যাওয়ার ঝুঁকিতে থাকা অবজেক্টগুলির গভীর অনুলিপি তৈরি করে।


2
"চূড়ান্ত সমস্যাটি হ'ল এটি কেবলমাত্র রেফারেন্সটি অপরিবর্তিত করে প্রয়োগ করে" - অস্পষ্ট, জাভা নিজেই এটিকে প্রতিরোধ করে। কোনও পদ্ধতিতে পাস করা একটি ভেরিয়েবলের সেই পদ্ধতি দ্বারা তার রেফারেন্স পরিবর্তন করা যায় না।
ম্যাডব্রেকস

পোস্ট করার আগে দয়া করে গবেষণা করুন ... স্ট্যাকওভারফ্লো / প্রশ্ন
ড্যারেল টিগু

সহজভাবে, করা হলে সত্য যে রেফারেন্স উল্লেখ পরিবর্তন করা যাবে না থাকত, তবে আত্মরক্ষামূলক-অনুলিপি, অপরিবর্তনীয়তা কোন আলোচনা চূড়ান্ত শব্দ, ইত্যাদি জন্য কোন প্রয়োজন হবে
ড্যারেল Teague

হয় আপনি আমাকে ভুল বোঝাবুঝি করছেন, বা আপনার ভুল হয়েছে। যদি আমি কোনও পদ্ধতির কোনও অবজেক্ট রেফারেন্সটি পাস করি এবং সেই পদ্ধতিটি তাকে পুনরায় নিয়োগ দেয় তবে পদ্ধতিটি তার কার্য সম্পাদন সম্পূর্ণ করার পরে কলিংয়ের জন্য মূল রেফারেন্স অক্ষত থাকে। জাভা কঠোরভাবে পাস-বাই-মান- আমি কোনও গবেষণা করিনি বলে দৃ to়তার সাথে আপনি দৃ bra়ভাবে অহঙ্কারী।
ম্যাডব্রেকস

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

0

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

যাইহোক, আমি সাধারণত এগুলি রিফ্যাক্টরিং শেষে অতিরিক্তহীন হিসাবে অপসারণ করি।


-1

মিশেলের পোস্টটি অনুসরণ করুন। আমি নিজে এটি ব্যাখ্যা করার জন্য নিজেকে অন্য একটি উদাহরণ তৈরি করেছি। আমি আশা করি এটি সাহায্য করতে পারে।

public static void main(String[] args){
    MyParam myParam = thisIsWhy(new MyObj());
    myParam.setArgNewName();

    System.out.println(myParam.showObjName());
}

public static MyParam thisIsWhy(final MyObj obj){
    MyParam myParam = new MyParam() {
        @Override
        public void setArgNewName() {
            obj.name = "afterSet";
        }

        @Override
        public String showObjName(){
            return obj.name;
        }
    };

    return myParam;
}

public static class MyObj{
    String name = "beforeSet";
    public MyObj() {
    }
}

public abstract static class MyParam{
    public abstract void setArgNewName();
    public abstract String showObjName();
}

উপরের কোড, পদ্ধতি থেকে thisIsWhy () , আসলে আমরা দায়িত্ব অর্পণ করা হয়নি [যুক্তি MyObj obj] একটি থেকে বাস্তব রেফারেন্স MyParam হবে। পরিবর্তে, আমরা মাইপ্যারামের পদ্ধতিতে কেবল [যুক্তি মাইওবজ আপত্তি] ব্যবহার করি।

তবে আমরা এই পদ্ধতিটি শেষ করার পরে কেন () , আর্গুমেন্ট (অবজেক্ট) মায়োবজ এখনও থাকা উচিত?

মত এটি করা উচিত মনে হয়, কারণ আমরা প্রধান দেখতে পারেন আমরা এখনও পদ্ধতি কল showObjName () এবং এটি পৌঁছাতে প্রয়োজন obj । মাইপ্রাম এখনও পদ্ধতিটি যুক্তিতে ব্যবহার / পৌঁছে দেবে এমনকি পদ্ধতিটি ইতিমধ্যে ফিরে আসছিল!

জাভা কীভাবে এটি অর্জন করতে পারে একটি অনুলিপি তৈরি করতে পারে এটি মাইপরাম অবজেক্টের ভিতরে মাইওবজ আপত্তিটির একটি গোপন রেফারেন্স (তবে এটি মাইপরামের কোনও আনুষ্ঠানিক ক্ষেত্র নয় যাতে আমরা এটি দেখতে পারি না)

যেহেতু আমরা "showObjName" বলি, এটি সংশ্লিষ্ট মান পেতে সেই রেফারেন্সটি ব্যবহার করবে।

তবে আমরা যদি যুক্তিটিকে চূড়ান্তভাবে না রাখি, যা এমন পরিস্থিতির দিকে নিয়ে যায় যা আমরা মায়োবজ আপত্তিটিকে নতুন মেমরি (অবজেক্ট) পুনরায় সাইন করতে পারি ।

প্রযুক্তিগতভাবে কোনও সংঘর্ষ নেই! যদি আমাদের তা করার অনুমতি দেওয়া হয় তবে নীচে পরিস্থিতি হবে:

  1. আমাদের কাছে এখন একটি লুকানো [মাইওবজ আপত্তি] একটি [মেগরি এ অব মেমরি] এখন মাইপরাম অবজেক্টে রয়েছে।
  2. আমাদের কাছে আরও একটি [মাইওবজ আপত্তি] রয়েছে যা একটি [মেমরি বি'র স্তূপে] যুক্তির পয়েন্ট যা এখন এই পদ্ধতিতে লাইভ করে।

কোনও সংঘাত নেই, তবে "কনফিউজিং !!" কারণ তারা সবাই একই "রেফারেন্স নাম" ব্যবহার করছে যা "আপত্তি"

এটি এড়াতে, প্রোগ্রামারটিকে "ভুল প্রবণ" কোডটি এড়াতে এটিকে "চূড়ান্ত" হিসাবে সেট করুন।

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