জাভা কি "পাস-বাই-রেফারেন্স" বা "পাস-বাই-মান"?


6576

আমি সবসময় ভেবেছিলাম জাভা পাস-বাই-রেফারেন্স

তবে, আমি বেশ কয়েকটি ব্লগ পোস্ট দেখেছি (উদাহরণস্বরূপ, এই ব্লগ ) যা দাবি করে যে এটি তা নয়।

তারা যে পার্থক্যটি করছে তা আমি বুঝতে পারি বলে আমি মনে করি না।

এর ব্যাখ্যা কী?


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

119
মূল্যায়ন কৌশল নিবন্ধে পাওয়া পরিভাষাটি আমি ধারাবাহিকভাবে ব্যবহার করার চেষ্টা করি । এটি লক্ষ করা উচিত যে, নিবন্ধটি শর্তাবলী সম্প্রদায়ের দ্বারা বিস্তরভাবে পরিবর্তিত হওয়া সত্ত্বেও, এটি জোর দেয় যে শব্দার্থবিজ্ঞানের পক্ষে call-by-valueএবং call-by-referenceঅত্যন্ত গুরুত্বপূর্ণ উপায়ে পৃথক । (ব্যক্তিগতভাবে আমি ব্যবহার করতে পছন্দ call-by-object-sharingউপর এই দিন call-by-value[-of-the-reference], এই একটি উচ্চ পর্যায়ে শব্দার্থবিদ্যা বর্ণনা এবং সাথে বিরোধ তৈরি করে না call-by-value, যা হয় অন্তর্নিহিত বাস্তবায়ন।)

59
@ গ্র্যাভিটি: আপনি কি যেতে পারেন এবং একটি বিশাল বিলবোর্ড বা অন্য কিছুতে আপনার মন্তব্য রাখতে পারেন? সংক্ষেপে পুরো বিষয়টি। এবং এটি দেখায় যে এই পুরো জিনিসটি শব্দার্থক। যদি আমরা কোনও রেফারেন্সের বেস সংজ্ঞাতে একমত না হই, তবে আমরা এই প্রশ্নের উত্তরের বিষয়ে একমত হব না :)
ম্যাডকনান

29
আমি মনে করি যে বিভ্রান্তিটি "রেফারেন্স বাই পাস" বনাম "রেফারেন্স শব্দার্থবিজ্ঞান"। জাভা হল রেফারেন্স শব্দার্থক সহ পাস-বাই-মান value
স্প্র্যাফ

11
@ গ্র্যাভিটি, আপনি যখন একেবারে ঠিক বলেছেন যে সি ++ থেকে আগত লোকেরা স্বতঃস্ফূর্তভাবে "রেফারেন্স" শব্দটি সম্পর্কে আলাদা স্বজ্ঞাত সেট রাখবেন, আমি ব্যক্তিগতভাবে বিশ্বাস করি যে শরীরটি "বাই" দিয়ে আরও কবর দেওয়া হয়েছে। "পাস বাই" বিভ্রান্তিকর যে এটি জাভাতে "পাসিং এ" থেকে একেবারেই স্বতন্ত্র। সি ++ তে, তবে এটি চূড়ান্তভাবে নয়। সি ++ তে আপনি "একটি রেফারেন্স পাস করে" বলতে পারেন এবং এটি বোঝা গেছে যে এটি swap(x,y)পরীক্ষায় উত্তীর্ণ হবে

উত্তর:


5838

জাভা সর্বদা পাস-বাই-মান হয় । দুর্ভাগ্যক্রমে, যখন আমরা কোনও বস্তুর মান পাস করি তখন আমরা এর রেফারেন্সটি পাস করি। এটি প্রাথমিকভাবে বিভ্রান্তিকর।

এটা এইভাবেই চলে:

public static void main(String[] args) {
    Dog aDog = new Dog("Max");
    Dog oldDog = aDog;

    // we pass the object to foo
    foo(aDog);
    // aDog variable is still pointing to the "Max" dog when foo(...) returns
    aDog.getName().equals("Max"); // true
    aDog.getName().equals("Fifi"); // false
    aDog == oldDog; // true
}

public static void foo(Dog d) {
    d.getName().equals("Max"); // true
    // change d inside of foo() to point to a new Dog instance "Fifi"
    d = new Dog("Fifi");
    d.getName().equals("Fifi"); // true
}

উপরের উদাহরণে aDog.getName()এখনও ফিরে আসবে "Max"। মান aDogমধ্যে mainফাংশনে পরিবর্তিত না হয় fooসঙ্গে Dog "Fifi"যেমন বস্তুর রেফারেন্স মান দ্বারা পাস করা হয়েছে। যদি রেফারেন্স দ্বারা গৃহীত হয়, তারপর aDog.getName()মধ্যে mainফিরে আসবে "Fifi"থেকে কল পর foo

অনুরূপভাবে:

public static void main(String[] args) {
    Dog aDog = new Dog("Max");
    Dog oldDog = aDog;

    foo(aDog);
    // when foo(...) returns, the name of the dog has been changed to "Fifi"
    aDog.getName().equals("Fifi"); // true
    // but it is still the same dog:
    aDog == oldDog; // true
}

public static void foo(Dog d) {
    d.getName().equals("Max"); // true
    // this changes the name of d to be "Fifi"
    d.setName("Fifi");
}

উপরের উদাহরণে, Fifiকুকুরটির নাম ডাকার পরে কি foo(aDog)কারণ বস্তুর নামটি ভিতরে স্থাপন করা হয়েছিল foo(...)। যে কোনও ক্রিয়াকলাপ fooসম্পাদন করে dসেগুলি এমন যে সমস্ত ব্যবহারিক উদ্দেশ্যে তারা সম্পাদিত হয় aDogতবে ভেরিয়েবলের মান নিজেই পরিবর্তন করা সম্ভব হয় নাaDog


263
এটি কি অভ্যন্তরীণ বিবরণ দিয়ে কিছুটা বিভ্রান্ত করছে না? 'রেফারেন্সটি পাস করা' এবং 'কোনও রেফারেন্সের মান পাস করার' মধ্যে কোনও ধারণাগত পার্থক্য নেই বলে ধরে নেওয়া, আপনার অর্থ 'অবজেক্টের অভ্যন্তরীণ পয়েন্টারের মান' mean
izb

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

300
@ লোরেঞ্জো: না, জাভাতে সমস্ত কিছু মান দিয়ে যায়। প্রিমিটিভগুলি মান দ্বারা পাস হয় এবং অবজেক্টের উল্লেখগুলি মান দ্বারা পাস হয় by বস্তুগুলি নিজেরাই কোনও পদ্ধতিতে কখনই প্রেরণ করা হয় না, তবে বস্তুগুলি সর্বদা গাদা থাকে এবং কেবলমাত্র বস্তুর একটি রেফারেন্স পদ্ধতিতে প্রেরণ করা হয়।
এস্কো লুনটলা

294
অবজেক্ট পাসিং কল্পনা করার জন্য আমার ভাল চেষ্টা: একটি বেলুনটি কল্পনা করুন। একটি fxn কল করা বেলুনের সাথে দ্বিতীয় স্ট্রিং বেঁধে ফ্যাক্সনের সাথে লাইনটি দেওয়ার মতো। প্যারামিটার = নতুন বেলুন () সেই স্ট্রিংটি কেটে একটি নতুন বেলুন তৈরি করবে (তবে এটির আসল বেলুনে কোনও প্রভাব নেই)। প্যারামিটার.পপ () এখনও এটি পপ করবে যদিও এটি স্ট্রিংটিকে একই, মূল বেলুনের সাথে অনুসরণ করে। জাভা মান দ্বারা পাস হয়, তবে পাস করা মান গভীর হয় না, এটি সর্বোচ্চ স্তরে থাকে, অর্থাত্ একটি আদিম বা পয়েন্টার। এমন একটি গভীর পাস-ভ্যালু দিয়ে বিভ্রান্ত করবেন না যেখানে অবজেক্টটি পুরোপুরি ক্লোন করা এবং পাস করা হয়েছে।
dhackner

150
বিভ্রান্তিকর বিষয় হ'ল বস্তুর উল্লেখগুলি আসলে পয়েন্টার। শুরুতে এসইএন তাদের পয়েন্টার হিসাবে ডেকেছিল। তারপরে বিপণন জানিয়েছিল যে "পয়েন্টার" একটি খারাপ শব্দ। তবে আপনি এখনও নালপয়েন্টারএক্সসেপশনে "সঠিক" নামকরণটি দেখতে পাচ্ছেন।
অধ্যাপক ফ্যালকেন চুক্তি

3035

আমি শুধু লক্ষ্য করেছি আপনি আমার নিবন্ধ রেফারেন্স ।

জাভা স্পেস বলছে যে জাভার সমস্ত কিছুই পাস-বাই-ভ্যালু। জাভাতে "পাস-বাই-রেফারেন্স" বলে কোনও জিনিস নেই।

এটি বোঝার মূল কথাটি এটির মতো something

Dog myDog;

হয় না একটি কুকুর; এটি আসলে একটি ব্যাপার পয়েন্টার একটি কুকুর রয়েছে।

এর অর্থ কী, যখন আপনার কাছে থাকে

Dog myDog = new Dog("Rover");
foo(myDog);

আপনি মূলত পদ্ধতিতে তৈরি বস্তুর ঠিকানাটি পাস করছেন ।Dogfoo

(আমি মূলত বলি কারণ জাভা পয়েন্টারগুলি সরাসরি ঠিকানা নয়, তবে সেগুলি সম্পর্কে সেভাবে ভাবা সহজ)

মনে করুন Dogঅবজেক্টটি মেমরির ঠিকানাতে অবস্থান করে 42 This এর অর্থ আমরা পদ্ধতিতে 42 পাস করি।

পদ্ধতি হিসাবে হিসাবে সংজ্ঞায়িত করা হয়

public void foo(Dog someDog) {
    someDog.setName("Max");     // AAA
    someDog = new Dog("Fifi");  // BBB
    someDog.setName("Rowlf");   // CCC
}

আসুন দেখুন কি হচ্ছে।

  • প্যারামিটারটি someDogমান 42 এ সেট করা আছে
  • "এএএ" লাইনে
    • someDogএটি নির্দেশিত দিকে অনুসরণ করা Dogহয় ( Dogঠিকানার ঠিকানা 42)
    • যে Dog(ঠিকানা 42 এর এক) তার নাম পরিবর্তন করতে সর্বোচ্চ বলা হয়
  • লাইনে "বিবিবি"
    • একটি নতুন Dogতৈরি করা হয়। ধরা যাক তিনি 74 নম্বর ঠিকানায় আছেন
    • আমরা someDog74 এ পরামিতি নির্ধারণ করি
  • লাইনে "সিসিসি"
    • কিছুডগ অনুসরণ করে Dogএটি নির্দেশ করে ( Dogঠিকানার ঠিকানাতে বস্তু)
    • এটি Dog(74৪ পৃষ্ঠার একটিতে) তার নাম পরিবর্তন করে রাউল্ফ করতে বলা হয়েছে
  • তারপরে, আমরা ফিরে আসি

এখন পদ্ধতির বাইরে কী ঘটে যায় সে সম্পর্কে ভাবি:

কি myDogপরিবর্তন?

চাবি আছে।

মনে রাখবেন যে রাখা myDogএকটি হল পয়েন্টার , এবং একটি প্রকৃত Dog, উত্তর নেই। myDogএখনও মান আছে 42; এটি এখনও মূলটির দিকে ইঙ্গিত করছে Dog(তবে মনে রাখবেন যে লাইন "এএএ" এর কারণে, এর নামটি এখন "সর্বোচ্চ" - এখনও একই কুকুর; myDogএর মান পরিবর্তন হয়নি))

কোনও ঠিকানা অনুসরণ করা এবং এর শেষে যা রয়েছে তা পরিবর্তন করা পুরোপুরি বৈধ ; তবে ভেরিয়েবল পরিবর্তন হয় না।

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

সি ++, অ্যাডা, পাস্কাল এবং অন্যান্য ভাষায় যা পাস-বাই-রেফারেন্সকে সমর্থন করে, আপনি আসলে যে ভেরিয়েবলটি পাস করেছিলেন তা পরিবর্তন করতে পারেন।

জাভা যদি পাস-বাই-রেফারেন্স শব্দার্থবিজ্ঞান থাকে তবে fooআমরা উপরে বর্ণিত পদ্ধতিটি বিবিবি লাইনে myDogনির্ধারিত someDogহওয়ার সময় কোথায় পয়েন্টিং করা হবে তা পরিবর্তিত হত ।

ভেরিয়েবলটি পাস হয়ে যাওয়ার জন্য রেফারেন্স প্যারামিটারগুলি ভেবে রাখুন alias যখন উপনামটি বরাদ্দ করা হয়, তেমনি ভেরিয়েবলটিও পাস করা হয়েছিল।


164
এই কারণেই সাধারণ বিরতি "জাভাতে পয়েন্টার নেই" এত বিভ্রান্তিকর।
বেসকা

134
আপনি ভুল, ইমো। "মনে রাখবেন যে মাইডগ একটি পয়েন্টার, এবং একটি আসল কুকুর নয়, উত্তরটি কোনও নয় my মাইডগের এখনও মূল্য আছে 42; এটি এখনও মূল কুকুরটির দিকে নির্দেশ করছে" " মাইডগের মান 42 হয় তবে এর নামের যুক্তিতে এখন // এএএ লাইনটিতে "রোভার" না দিয়ে "সর্বাধিক" রয়েছে।
üzgür

180
এই ভাবে চিন্তা করুন। "আনআরবারলোকেশন" নামে একটি কাগজের স্লিপে কারও কারও অ্যান আরবার, এমআই (আমার শহর, গ্লু ব্লু!) ঠিকানা রয়েছে। আপনি এটি "মাইডেস্টিনেশন" নামক কাগজের টুকরোতে অনুলিপি করেন। আপনি "মাইডেস্টিনেশন" এ যান এবং একটি গাছ লাগাতে পারেন। আপনি সেই জায়গাটিতে শহরটি সম্পর্কে কিছু পরিবর্তন করতে পারেন, তবে এটি কোনও কাগজে লেখা LAT / LON পরিবর্তন করে না। আপনি "মাইডেস্টিনেশন" -তে LAT / LON পরিবর্তন করতে পারেন তবে এটি "annArborLocation" পরিবর্তন করে না। এটা কি সাহায্য করে?
স্কট স্ট্যাঞ্চফিল্ড

43
@ স্কট স্ট্যানচফিল্ড: আমি আপনার নিবন্ধটি প্রায় এক বছর আগে পড়েছিলাম এবং এটি আমার পক্ষে জিনিসগুলি পরিষ্কার করতে সত্যই সহায়তা করেছিল। ধন্যবাদ! আমি নম্রভাবে কিছুটা সংযোজনের পরামর্শ দিতে পারি: আপনার উল্লেখ করা উচিত যে সেখানে একটি নির্দিষ্ট শব্দ রয়েছে যা "এই মূল্য দ্বারা কল যেখানে মানটি একটি রেফারেন্স" এই রূপটি বর্ণনা করে যা বারবারা লিসকভ তার সিএলইউ ভাষার মূল্যায়ন কৌশল বর্ণনা করার জন্য আবিষ্কার করেছিলেন? 1974, যেমন আপনার নিবন্ধের ঠিকানাগুলির মত বিভ্রান্তি এড়াতে: ভাগ করে নেওয়ার মাধ্যমে কল করুন (কখনও কখনও বস্তু ভাগ করে নেওয়ার মাধ্যমে কল বলে বা কেবলমাত্র বস্তু দ্বারা কল করা হয় ), যা শব্দার্থক শব্দটিকে পুরোপুরি বর্ণনা করে।
Jörg ডব্লু মিট্টাগ

29
@ জিভর্গ - সি / সি ++ টি ভাষা "পয়েন্টার" ধারণার মালিক নয়। অন্যান্য ভাষা রয়েছে যা পয়েন্টার ব্যবহার করে তবে পয়েন্টারগুলিতে একই ধরণের হেরফেরির অনুমতি দেয় না যা সি / সি ++ অনুমতি দেয়। জাভা পয়েন্টার আছে; তারা কেবল দুষ্টামি থেকে রক্ষা পেয়েছে।
স্কট স্ট্যাঞ্চফিল্ড

1739

জাভা সর্বদা মান দ্বারা আর্গুমেন্টগুলি পাস করে , রেফারেন্স দ্বারা নয়।


আমি এটি একটি উদাহরণের মাধ্যমে ব্যাখ্যা করি :

public class Main {

     public static void main(String[] args) {
          Foo f = new Foo("f");
          changeReference(f); // It won't change the reference!
          modifyReference(f); // It will modify the object that the reference variable "f" refers to!
     }

     public static void changeReference(Foo a) {
          Foo b = new Foo("b");
          a = b;
     }

     public static void modifyReference(Foo c) {
          c.setAttribute("c");
     }

}

আমি পদক্ষেপে এটি ব্যাখ্যা করব:

  1. fপ্রকারের নামের একটি রেফারেন্স ঘোষণা করে Fooএটিকে Fooকোনও অ্যাট্রিবিউট দিয়ে টাইপের একটি নতুন অবজেক্ট বরাদ্দ করুন "f"

    Foo f = new Foo("f");

    এখানে চিত্র বর্ণনা লিখুন

  2. পদ্ধতির দিক থেকে, কোনও Fooনামের সাথে একটি উল্লেখ উল্লেখ aকরা হয় এবং এটি প্রাথমিকভাবে নির্ধারিত হয় null

    public static void changeReference(Foo a)

    এখানে চিত্র বর্ণনা লিখুন

  3. আপনি পদ্ধতিটি কল করার সাথে সাথে changeReference, রেফারেন্সটি aঅবজেক্টটিকে বরাদ্দ করা হবে যা আর্গুমেন্ট হিসাবে পাস করা হবে।

    changeReference(f);

    এখানে চিত্র বর্ণনা লিখুন

  4. bপ্রকারের নামের একটি রেফারেন্স ঘোষণা করে Fooএটিকে Fooকোনও অ্যাট্রিবিউট দিয়ে টাইপের একটি নতুন অবজেক্ট বরাদ্দ করুন "b"

    Foo b = new Foo("b");

    এখানে চিত্র বর্ণনা লিখুন

  5. a = bরেফারেন্সের জন্য নতুন অ্যাসাইনমেন্ট দেয় a, না f যার, যার বৈশিষ্ট্য এটি "b"

    এখানে চিত্র বর্ণনা লিখুন

  6. আপনি কল modifyReference(Foo c)পদ্ধতি হিসাবে , একটি রেফারেন্স cতৈরি করা হয় এবং বৈশিষ্ট্য সঙ্গে অবজেক্ট বরাদ্দ করা হয় "f"

    এখানে চিত্র বর্ণনা লিখুন

  7. c.setAttribute("c");রেফারেন্সটি cনির্দেশ করে এমন বস্তুর বৈশিষ্ট্য পরিবর্তন করবে এবং এটি একই বস্তু যা রেফারেন্স এতে fনির্দেশ করে।

    এখানে চিত্র বর্ণনা লিখুন

আমি আশা করি আপনি এখন বুঝতে পারবেন কীভাবে জাভায় আর্গুমেন্ট হিসাবে অজানাগুলি কাজ করে :)


82
+1 দুর্দান্ত জিনিস। ভাল ডায়াগ্রাম। আমি এখানে একটি সুন্দর সংক্ষিপ্ত পৃষ্ঠাও পেয়েছি adp-gmbh.ch/php/pass_by_references.html ঠিক আছে আমি স্বীকার করি যে এটি পিএইচপিতে লেখা হয়েছে, তবে এটি যে পার্থক্যটি গুরুত্বপূর্ণ বলে আমি তা বুঝতে পেরেছি (এবং কীভাবে এই পার্থক্যটিকে সামলানো যায়) আপনার চাহিদা).
ডেভএম

5
@ ইঞ্জি। ফুয়াদ এটি একটি দুর্দান্ত ব্যাখ্যা তবে aএকই অবজেক্টের দিকে নির্দেশ করলে f(এবং অবজেক্টটির নিজস্ব কপিটি কখনই fপয়েন্ট করে না) ব্যবহার করে করা বস্তুটিতে যে কোনও পরিবর্তন করা aউচিত পাশাপাশি পরিবর্তন করা উচিত f(যেহেতু তারা উভয় একই বস্তুর সাথে কাজ করছে) ), তাই কোনও সময়ে aঅবশ্যই অবজেক্ট পয়েন্টগুলির নিজস্ব কপিটি পেতে হবে f
0x6C38

14
@ এমআরডি যখন 'ক' একই বস্তু 'এফ' এর দিকেও ইঙ্গিত করে, তখন 'ক' এর মাধ্যমে object বস্তুটিতে যে কোনও পরিবর্তন করা হয় তা 'চ' এর মাধ্যমেও পর্যবেক্ষণযোগ্য, তবে এটি 'এফ' পরিবর্তন করে না। 'f' এখনও একই অবজেক্টের দিকে নির্দেশ করে। আপনি অবজেক্টটি পুরোপুরি পরিবর্তন করতে পারেন, তবে 'চ' এর দিকে কী নির্দেশ করে তা আপনি কখনও পরিবর্তন করতে পারবেন না। এটি এমন মৌলিক বিষয় যা কিছু কারণে কিছু লোক বুঝতে পারে না।
মাইক ব্রাউন

@ মাইকব্রাউন ... কি? এখন আপনি আমাকে বিভ্রান্ত করেছেন: এস। আপনি যা লিখেছেন তা 6 এবং 7 এর বিপরীতে নয়?
এভিল ওয়াশিং মেশিন

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

732

এটি আপনাকে জাভা কীভাবে সত্যিকার অর্থে কাজ করে সে সম্পর্কে কিছুটা অন্তর্দৃষ্টি দেবে যে আপনার পরবর্তী আলোচনায় জাভা রেফারেন্স দ্বারা পাস করা বা মান দ্বারা পাস করার বিষয়ে আপনি কেবল হাসবেন :-)

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

দ্বিতীয় ধাপটি মনে রাখবেন যে আপনি যখন কোনও অবজেক্টকে কোনও পদ্ধতিতে পাস করেন আপনি অবজেক্ট রেফারেন্সটি পাস করেন এবং অবজেক্টটি নিজেই নয়।

  • ছাত্র : মাস্টার, এর অর্থ জাভা কি পাস-রেফারেন্স হয়?
  • মাষ্টার : ঘাসফড়িং, না।

এখন চিন্তা করুন যে কোনও অবজেক্টের রেফারেন্স / ভেরিয়েবলটি কী /

  1. একটি ভেরিয়েবল বিটগুলি ধারণ করে যা JVM কে মেমরিতে রেফারেন্স করা অবজেক্টে (হিপ) কীভাবে পাবেন তা বলে tell
  2. কোনও পদ্ধতিতে তর্কগুলি পাস করার সময় আপনি রেফারেন্স ভেরিয়েবলটি পাস করেন না, তবে রেফারেন্স ভেরিয়েবলের বিটের একটি অনুলিপি । এরকম কিছু: 3ad086a। 3bad086a উত্তীর্ণ হওয়া অবজেক্টটিতে যাওয়ার উপায় উপস্থাপন করে।
  3. সুতরাং আপনি কেবল 3ad086a পেরিয়ে যাচ্ছেন যে এটি রেফারেন্সের মান।
  4. আপনি রেফারেন্সের মানটি পাস করছেন এবং নিজেই রেফারেন্সটি (এবং অবজেক্টটি নয়)।
  5. এই মানটি আসলে কপিড এবং পদ্ধতিতে দেওয়া হয়

নিম্নলিখিতটিতে (দয়া করে এটি সংকলন / সম্পাদন করার চেষ্টা করবেন না ...):

1. Person person;
2. person = new Person("Tom");
3. changeName(person);
4.
5. //I didn't use Person person below as an argument to be nice
6. static void changeName(Person anotherReferenceToTheSamePersonObject) {
7.     anotherReferenceToTheSamePersonObject.setName("Jerry");
8. }

কি ঘটেছে?

  • পরিবর্তনশীল ব্যক্তিটি # 1 লাইনে তৈরি করা হয় এবং এটি শুরুতে বাতিল হয় ull
  • একটি নতুন ব্যক্তি অবজেক্ট # 2 লাইনে তৈরি করা হয়, মেমরিতে সঞ্চিত থাকে এবং ভেরিয়েবল ব্যক্তিকে ব্যক্তি বস্তুর উল্লেখ দেওয়া হয়। অর্থাৎ এর ঠিকানা। যাক 3bad086a।
  • অবজেক্টের ঠিকানা সম্বলিত পরিবর্তনশীল ব্যক্তি লাইন # 3-এ ফাংশনে প্রেরণ করা হয়।
  • লাইনে # 4 আপনি নীরবতার শব্দ শুনতে পারেন
  • # 5 লাইনে মন্তব্যটি দেখুন
  • একটি পদ্ধতি স্থানীয় পরিবর্তনশীল - আরেকটি রেফারেন্সটোস্টেম্পারসনবজেক্ট - তৈরি করা হয় এবং তারপরে লাইনে # 6 লাইনে যাদু আসে:
    • পরিবর্তনশীল / রেফারেন্স ব্যক্তিটি বিট-বিট-বিট অনুলিপি করে ফাংশনের অভ্যন্তরে অন্য রেফারেন্সটোওসেম্পারসনঅবজেক্টে প্রেরণ করা হয় ।
    • ব্যক্তির কোনও নতুন দৃষ্টান্ত তৈরি হয় না।
    • " ব্যক্তি " এবং " আরেকটি রেফারেন্সটিওসেম্পারসনবজেক্ট " উভয়ই 3ad086a এর সমান মান ধারণ করে।
    • এটি চেষ্টা করে দেখুন না তবে ব্যক্তি == আরেকটি রেফারেন্সটিওসেম্পারসনঅজেক্টটি সত্য হবে।
    • উভয় ভেরিয়েবলের রেফারেন্সের আইডেন্টিকাল কপি রয়েছে এবং তারা উভয়ই একই ব্যক্তি অবজেক্ট, হিপ-এর একই জিনিস এবং নোট কপি নয়।

একটি ছবি হাজার শব্দের সমান:

মান দ্বারা পাস

নোট করুন যে অন্যটি রেফারেন্সটওসেম্পারসনঅজেক্ট তীরগুলি বস্তুর দিকে পরিচালিত হয়, ভেরিয়েবল ব্যক্তির দিকে নয়!

আপনি এটা তারপর পাননি শুধু আমাকে বিশ্বাস এবং মনে রাখবেন এটা বলতে যে ভালো জাভা মান পাস হয় । ভাল, রেফারেন্স মান দ্বারা পাস । ওহ ভাল, ভেরিয়েবল-মানটি পাস-কপি-অন-কপিরাইটের চেয়ে ভাল! ;)

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

আপনি সর্বদা রেফারেন্সের মান বিটের একটি অনুলিপি পাস করেন!

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

জাভা হ'ল পাস-ভ্যালু কারণ একটি পদ্ধতির ভিতরে আপনি রেফারেন্স করা অবজেক্টটিকে যতটা চান পরিবর্তন করতে পারবেন তবে আপনি যতই চেষ্টা করুন না কেন আপনি কখনই পাস হওয়া ভেরিয়েবলটি রেফারেন্স করতে পারবেন না (পি _ _ _ নয়) _ _ _ _ _ একই বস্তু যাই হোক না কেন!


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


অবশ্যই আপনি এটি সংক্ষিপ্তভাবে কাটতে পারেন এবং কেবল বলেছেন যে জাভা পাস-বাই-ভ্যালু!


5
আপনি কি পয়েন্টার বলতে চাইছেন? .. যদি আমি এটি সঠিকভাবে পাই তবে public void foo(Car car){ ... }, carএটি স্থানীয় fooএবং এটিতে অবজেক্টের হিপ অবস্থান রয়েছে? সুতরাং যদি আমি carএর মানটি পরিবর্তিত করি car = new Car(), তবে এটি গাদাতে পৃথক অবজেক্টের দিকে নির্দেশ করবে? এবং যদি আমি carএর সম্পত্তি মূল্য দ্বারা পরিবর্তিত করি car.Color = "Red", তবে স্তূপের পয়েন্টের অবজেক্টটি carপরিবর্তিত হবে। এছাড়াও, এটি সি # তেও কি একই? অনুগ্রহপূর্বক জবাব দিবেন! ধন্যবাদ!
ডিপিপি

11
@domanokz আপনি আমাকে হত্যা করছেন, দয়া করে সেই শব্দটি আবার বলবেন না! ;) নোট করুন যে আমি 'রেফারেন্স' না বলেও এই প্রশ্নের উত্তর দিতে পারতাম। এটি একটি পরিভাষা সংক্রান্ত সমস্যা এবং এটি 'পি' আরও খারাপ করে দেয়। দুর্ভাগ্যক্রমে এ সম্পর্কে আমার এবং স্কটের বিভিন্ন মতামত রয়েছে। আমি মনে করি আপনি জাভাতে এটি কীভাবে কাজ করে, আপনি এখন এটিকে বাই-ভ্যালু, বাই-অবজেক্ট শেয়ারিং, কপি-অফ-দ্য ভেরিয়েবল-মান বলতে পারেন বা অন্য কিছু নিয়ে নির্দ্বিধায় আসতে পারেন! আপনি যেভাবে এটি কাজ করেন এবং টাইপ অবজেক্টের ভেরিয়েবলের মধ্যে কী রয়েছে তা আমি সত্যিই যত্নবান না! কেবলমাত্র একটি পোষ্ট বক্স ঠিকানা! ;)
মার্সেলাস ওয়ালেস

9
আপনি কি কেবল একটি রেফারেন্স পাশ করেছেন বলে মনে হচ্ছে ? আমি জাভা এখনও একটি অনুলিপি পাস-বাই-রেফারেন্স ভাষা হিসাবে এই সত্যটি জয় করতে চলেছি। এটি একটি অনুলিপিযুক্ত রেফারেন্স হিসাবে পরিভাষা পরিবর্তন করে না। উভয়ই রেফারেন্স একই বস্তুর দিকে নির্দেশ করে। এটি পিউরিস্টের যুক্তি ...
জন স্ট্রিকলার

3
সুতরাং তাত্ত্বিক লাইনে ড্রপ # 9 System.out.println(person.getName());কি প্রদর্শিত হবে? "টম" বা "জেরি"? এটিই শেষ জিনিস যা আমাকে এই বিভ্রান্তিকে বাধা দিতে সহায়তা করবে।
দ্য ব্রেনি

1
" রেফারেন্সের মান " অবশেষে এটি আমার কাছে ব্যাখ্যা করেছিল।
আলেকজান্ডার শুবার্ট

689

জাভা সর্বদা মান দ্বারা পাস হয়, কোনও ব্যতিক্রম ছাড়াই কখনও হয় না

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

সুতরাং, যখন একটি পদ্ধতি কল

  • আদিম যুক্তিগুলির জন্য ( int, longইত্যাদি), মান দ্বারা পাস হ'ল আদিমের আসল মান (উদাহরণস্বরূপ, 3)।
  • বস্তুর জন্য, মান দ্বারা পাস হ'ল অবজেক্টের রেফারেন্সের মান ।

সুতরাং যদি আপনার doSomething(foo)এবং public void doSomething(Foo foo) { .. }দুটি Foos রেফারেন্সগুলি অনুলিপি করে একই জিনিসকে নির্দেশ করে।

স্বাভাবিকভাবেই, কোনও বস্তুর রেফারেন্সকে মান দিয়ে পাস করা দেখতে অনেকটা দেখতে পাওয়া যায় (এবং এটি থেকে অনুশীলনে পৃথক পৃথক) রেফারেন্সের মাধ্যমে কোনও বস্তু পাস করা।


7
আদিমদের মানগুলি যেহেতু অপরিবর্তনীয় (স্ট্রিংয়ের মতো), তাই দুটি ক্ষেত্রে পার্থক্য আসলেই প্রাসঙ্গিক নয়।
পাওলো ইবারম্যান

4
যথাযথভাবে। আপনারা পর্যবেক্ষণযোগ্য জেভিএম আচরণের মাধ্যমে বলতে পারেন যে, আদিমরা রেফারেন্স দ্বারা পাস করা যেতে পারে এবং স্তূপে বাস করতে পারে। তারা তা করে না তবে এটি কোনওভাবেই পর্যবেক্ষণযোগ্য নয়।
মাধ্যাকর্ষণ

6
আদিমরা কি অপরিবর্তনীয়? জাভা 7 এ কি নতুন?
ব্যবহারকারী 85421

4
পয়েন্টারগুলি পরিবর্তনযোগ্য, সাধারণভাবে আদিম পরিবর্তনীয় mut স্ট্রিংও আদিম নয়, এটি একটি বস্তু। তদুপরি, স্ট্রিংয়ের অন্তর্নিহিত কাঠামোটি একটি পরিবর্তনীয় অ্যারে ray এ সম্পর্কে একমাত্র স্থায়ী জিনিস হ'ল দৈর্ঘ্য, এটি অ্যারের সহজাত প্রকৃতি।
কিংফ্রিটো_5005

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

331

জাভা মান দ্বারা রেফারেন্স পাস।

সুতরাং আপনি যে রেফারেন্সটি পাস করবেন তা পরিবর্তন করতে পারবেন না।


27
তবে যে জিনিসটি "বারবার আর্গুমেন্টের মান আপনি পরিবর্তন করতে পারবেন না" এটি বার বার হয়ে যায় তা স্পষ্টতই মিথ্যা। আপনি এগুলি কোনও অন্য কোনও অবজেক্টের জন্য উল্লেখ করতে সক্ষম নাও হতে পারেন তবে তাদের পদ্ধতিগুলিতে কল করে আপনি তাদের বিষয়বস্তু পরিবর্তন করতে পারেন। আইএমও এর অর্থ আপনি উল্লেখের সমস্ত সুবিধা হারাবেন এবং কোনও অতিরিক্ত গ্যারান্টি পাবেন না।
টিম্ম্ম্ম

34
আমি কখনও বলিনি "আপনি আর্গুমেন্টে পাস হওয়া সামগ্রীর মান পরিবর্তন করতে পারবেন না"। আমি বলব "আপনি কোনও পদ্ধতি আর্গুমেন্ট হিসাবে পাস করা অবজেক্টের রেফারেন্সের মান পরিবর্তন করতে পারবেন না", এটি জাভা ভাষা সম্পর্কে সত্য বক্তব্য। স্পষ্টতই আপনি অবজেক্টের অবস্থা পরিবর্তন করতে পারবেন (যতক্ষণ না এটি অপরিবর্তনীয় নয়)।
ScArcher2

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

10
আপনি কি কেবল একটি রেফারেন্স পাশ করেছেন বলে মনে হচ্ছে ? আমি জাভা এখনও একটি অনুলিপি পাস-বাই-রেফারেন্স ভাষা হিসাবে এই সত্যটি জয় করতে চলেছি। এটি একটি অনুলিপিযুক্ত রেফারেন্স হিসাবে পরিভাষা পরিবর্তন করে না। উভয়ই রেফারেন্স একই বস্তুর দিকে নির্দেশ করে। এটি পিউরিস্টের যুক্তি ...
জন স্ট্রিকলার

3
জাভা কোনও বস্তুটি পাস করে না, এটি পয়েন্টারের মানটিকে অবজেক্টে পাস করে। এটি একটি নতুন ভেরিয়েবলের আসল অবজেক্টের সেই মেমরি অবস্থানে একটি নতুন পয়েন্টার তৈরি করে। আপনি যদি কোনও পদ্ধতিতে এই পয়েন্টার ভেরিয়েবলের মান (মেমরিের ঠিকানাটি এটি নির্দেশ করে) পরিবর্তন করেন, তবে পদ্ধতি কলারে ব্যবহৃত মূল পয়েন্টারটি অশোধিত থেকে যায়। আপনি যদি প্যারামিটারটিকে একটি রেফারেন্স বলছেন তবে সত্য যে এটি মূল রেফারেন্সের একটি অনুলিপি , মূল রেফারেন্স নিজেই এমন নয় যে এখন অবজেক্টের দুটি রেফারেন্স রয়েছে তার মানে এটি পাস-বাই-ভ্যালু
theferrit32

238

আমার কাছে "পাস-বাই-রেফারেন্স বনাম পাস-বাই-ভ্যালু" সম্পর্কে তর্ক করা খুব সহায়ক নয়।

আপনি যদি বলেন, "জাভা হ'ল পাস-বাই-ইন্ড (যেকোন বিষয় (রেফারেন্স / মান)", উভয় ক্ষেত্রেই, আপনি একটি সম্পূর্ণ উত্তর সরবরাহ করেন না। এখানে কিছু অতিরিক্ত তথ্য যা আশা করি মেমরিতে কী ঘটছে তা বুঝতে সহায়তা করবে।

জাভা প্রয়োগে পৌঁছানোর আগে স্ট্যাক / হিপে ক্র্যাশ কোর্স: মানগুলি স্ট্যান্ডে স্টাফের বাইরে চলে যায় সুন্দর সুশৃঙ্খল ফ্যাশনে, যেমন কোনও ক্যাফেটেরিয়ায় প্লেটের স্ট্যাক। গাদা মধ্যে স্মৃতি (ডায়নামিক মেমরি হিসাবে পরিচিত) হ্যাফাজার্ড এবং বিশৃঙ্খল। জেভিএম কেবল যেখানেই পারে জায়গা সন্ধান করে এবং এটি ব্যবহার করে এমন ভেরিয়েবলগুলি মুক্ত করে দেয়।

ঠিক আছে. প্রথমে, স্থানীয় আদিমরা স্ট্যাকের দিকে যায়। সুতরাং এই কোড:

int x = 3;
float y = 101.1f;
boolean amIAwesome = true;

এর ফলাফল:

স্ট্যাকের উপর আদিম

আপনি যখন কোনও বস্তু ঘোষণা এবং ইনস্ট্যান্ট করবেন। আসল বস্তুটি গাদা হয়ে যায়। স্ট্যাকের উপর কি যায়? স্তূপে বস্তুর ঠিকানা। সি ++ প্রোগ্রামাররা এটিকে একটি পয়েন্টার বলবে, তবে কিছু জাভা বিকাশকারী "পয়েন্টার" শব্দের বিরোধী। যাই হোক. শুধু জানি যে বস্তুর ঠিকানা স্ট্যাকের উপর যায় ack

তাই ভালো:

int problems = 99;
String name = "Jay-Z";

আব * ch ইচ এক!

একটি অ্যারে হ'ল একটি বস্তু, তাই এটি গাদা হয়ে যায়। এবং অ্যারের মধ্যে অবজেক্টস সম্পর্কে কি? তারা তাদের নিজস্ব গাদা স্থান পায় এবং প্রতিটি বস্তুর ঠিকানা অ্যারের ভিতরে যায়।

JButton[] marxBros = new JButton[3];
marxBros[0] = new JButton("Groucho");
marxBros[1] = new JButton("Zeppo");
marxBros[2] = new JButton("Harpo");

মার্কস ভাই

সুতরাং, আপনি যখন কোনও পদ্ধতি কল করবেন তখন কী পাস হবে? আপনি যদি কোনও বস্তুর মধ্যে পাস করেন তবে আপনি যা যা করছেন তা হ'ল অবজেক্টের ঠিকানা। কেউ কেউ ঠিকানার "মান" বলতে পারে এবং কেউ কেউ বলে যে এটি কেবলমাত্র অবজেক্টের একটি রেফারেন্স। এটি "রেফারেন্স" এবং "মান" প্রবক্তাদের মধ্যে পবিত্র যুদ্ধের উদ্ভব। আপনি যেটাকে এটাকে কল করেন তা ততটা গুরুত্বপূর্ণ নয় যে আপনি বুঝতে পেরেছেন যে যা যা যাচ্ছেন তা হল বস্তুর ঠিকানা।

private static void shout(String name){
    System.out.println("There goes " + name + "!");
}

public static void main(String[] args){
    String hisName = "John J. Jingleheimerschmitz";
    String myName = hisName;
    shout(myName);
}

একটি স্ট্রিং তৈরি হয়ে যায় এবং এর জন্য স্থানটি হিপগুলিতে বরাদ্দ করা হয় এবং স্ট্রিংয়ের ঠিকানাটি স্ট্যাকের মধ্যে সংরক্ষণ করা হয় এবং সনাক্তকারীকে দেওয়া হয় hisName, যেহেতু দ্বিতীয় স্ট্রিংয়ের ঠিকানাটি প্রথমটির মতো একই, কোনও নতুন স্ট্রিং তৈরি হয় নি এবং কোনও নতুন গাদা স্থান বরাদ্দ করা হয়নি, তবে স্ট্যাকের উপরে একটি নতুন শনাক্তকারী তৈরি করা হয়েছে। তারপরে আমরা কল করব shout(): একটি নতুন স্ট্যাক ফ্রেম তৈরি করা হবে এবং একটি নতুন শনাক্তকারী nameতৈরি করা হবে এবং ইতিমধ্যে বিদ্যমান স্ট্রিংয়ের ঠিকানা নির্ধারণ করা হয়েছে।

লা দা দি দা দা দা

সুতরাং, মান, রেফারেন্স? আপনি "আলু" বলুন।


7
তবে আপনার আরও জটিল উদাহরণ অনুসরণ করা উচিত ছিল যেখানে কোনও ফাংশন এমন কোনও ভেরিয়েবলের পরিবর্তনের জন্য প্রদর্শিত হয় যার ঠিকানার উল্লেখ রয়েছে।
ব্রায়ান পিটারসন

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

8
এটি জাভাতে কোনও "বাস্তবায়নের বিশদ" রয়েছে যা কখনই কোনও বস্তু স্মৃতিতে বাস করে তা বাস্তবে আপনাকে দেখাতে হবে না এবং বাস্তবে সেই তথ্য ফাঁস করা এড়াতে দৃ determined ়প্রতিজ্ঞ বলে মনে হচ্ছে । এটি বস্তুটিকে স্ট্যাকের মধ্যে ফেলতে পারে এবং আপনি কখনই জানতে পারবেন না। আপনি যদি যত্নশীল হন তবে আপনি ভুল জিনিসটির দিকে মনোনিবেশ করছেন - এবং এই ক্ষেত্রে এর অর্থ আসল সমস্যাটিকে উপেক্ষা করা।
সিএওও

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

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

195

কেবল বৈপরীত্যটি দেখানোর জন্য, নিম্নলিখিত সি ++ এবং জাভা স্নিপেটগুলি তুলনা করুন :

সি ++ এ: দ্রষ্টব্য: খারাপ কোড - মেমরি ফাঁস! তবে এটি বিন্দুটি প্রদর্শন করে।

void cppMethod(int val, int &ref, Dog obj, Dog &objRef, Dog *objPtr, Dog *&objPtrRef)
{
    val = 7; // Modifies the copy
    ref = 7; // Modifies the original variable
    obj.SetName("obj"); // Modifies the copy of Dog passed
    objRef.SetName("objRef"); // Modifies the original Dog passed
    objPtr->SetName("objPtr"); // Modifies the original Dog pointed to 
                               // by the copy of the pointer passed.
    objPtr = new Dog("newObjPtr");  // Modifies the copy of the pointer, 
                                   // leaving the original object alone.
    objPtrRef->SetName("objRefPtr"); // Modifies the original Dog pointed to 
                                    // by the original pointer passed. 
    objPtrRef = new Dog("newObjPtrRef"); // Modifies the original pointer passed
}

int main()
{
    int a = 0;
    int b = 0;
    Dog d0 = Dog("d0");
    Dog d1 = Dog("d1");
    Dog *d2 = new Dog("d2");
    Dog *d3 = new Dog("d3");
    cppMethod(a, b, d0, d1, d2, d3);
    // a is still set to 0
    // b is now set to 7
    // d0 still have name "d0"
    // d1 now has name "objRef"
    // d2 now has name "objPtr"
    // d3 now has name "newObjPtrRef"
}

জাভাতে,

public static void javaMethod(int val, Dog objPtr)
{
   val = 7; // Modifies the copy
   objPtr.SetName("objPtr") // Modifies the original Dog pointed to 
                            // by the copy of the pointer passed.
   objPtr = new Dog("newObjPtr");  // Modifies the copy of the pointer, 
                                  // leaving the original object alone.
}

public static void main()
{
    int a = 0;
    Dog d0 = new Dog("d0");
    javaMethod(a, d0);
    // a is still set to 0
    // d0 now has name "objPtr"
}

জাভাতে কেবল দুটি প্রকারের পাসিং রয়েছে: অন্তর্নির্মিত ধরণের মান অনুসারে এবং অবজেক্টের ধরণের জন্য পয়েন্টারের মান দ্বারা।


7
+1 আমি Dog **objPtrPtrসি ++ উদাহরণেও যুক্ত করব, আমরা পয়েন্টারটি কী "নির্দেশিত" তা পরিবর্তন করতে পারি।
আম্রো

1
তবে এটি জাভাতে প্রদত্ত প্রশ্নের উত্তর দেয় না। প্রকৃতপক্ষে, জাভা পদ্ধতির সমস্ত কিছুই পাস বাই ভ্যালু, এর চেয়ে বেশি কিছুই নয়।
tauitdnmd

2
এই উদাহরণটি কেবল প্রমাণ করে যে জাভা সি নং তে পয়েন্টারের খুব সমতুল্য ব্যবহার করে? সি এর মান দ্বারা পাস যেখানে মূলত শুধুমাত্র পড়া হয়? শেষে, এই পুরো থ্রেডটি বোধগম্য নয়
amdev


166

মূলত, অবজেক্ট প্যারামিটারগুলি পুনরায় নিয়োগ করা যুক্তিটিকে প্রভাবিত করে না, যেমন,

private void foo(Object bar) {
    bar = null;
}

public static void main(String[] args) {
    String baz = "Hah!";
    foo(baz);
    System.out.println(baz);
}

"Hah!"পরিবর্তে প্রিন্ট আউট হবে null। এই কাজ করার কারণটি barহ'ল মূল্যের একটি অনুলিপি baz, যা কেবলমাত্র একটি উল্লেখ "Hah!"। যদি এটি নিজেই প্রকৃত রেফারেন্স fooহত তবে তার সাথে নতুন সংজ্ঞা bazদেওয়া হত null


8
আমি বরং বলব যে বারটি রেফারেন্স বাজ (বা বাজ ওরফে) এর অনুলিপি, যা একই বস্তুকে প্রাথমিকভাবে নির্দেশ করে।
ম্যাক্সজুম

স্ট্রিং ক্লাস এবং অন্যান্য সমস্ত ক্লাসের মধ্যে কিছুটা আলাদা না?
মেহেদী কারামোসলি

152

আমি বিশ্বাস করতে পারি না যে কেউ এখনও বারবারা লিসকভের কথা উল্লেখ করেনি। অতঃপর যখন তাকে 1974 সালে CLU পরিকল্পিত, সে এই একই পরিভাষা সমস্যাতে পড়েছি এবং তিনি শব্দটি উদ্ভাবন শেয়ারিং দ্বারা কল (নামেও পরিচিত অবজেক্ট শেয়ারিং দ্বারা কল এবং বস্তু দ্বারা কল মান) "কলের এই নির্দিষ্ট ক্ষেত্রে জন্য যেখানে মান একটি রেফারেন্স "।


3
নামকরণে আমি এই পার্থক্যটি পছন্দ করি। এটি দুর্ভাগ্যজনক যে জাভা অবজেক্টগুলির জন্য ভাগ করে কলকে সমর্থন করে, তবে মান অনুসারে কল দেয় না (যেমন সি ++ আছে)। জাভা কেবলমাত্র প্রাথমিক তথ্য প্রকারের জন্য এবং সংমিশ্রিত ডেটা ধরণের জন্য নয়, কলকে কল সমর্থন করে।
ডেরেক মহর

2
আমি সত্যই মনে করি না যে আমাদের একটি অতিরিক্ত শব্দ প্রয়োজন - এটি কেবলমাত্র নির্দিষ্ট ধরণের মানের জন্য পাস-বাই-ভ্যালু। "আদি দ্বারা কল" যুক্ত করা কি কোনও ব্যাখ্যা যোগ করবে?
স্কট স্ট্যাঞ্চফিল্ড


সুতরাং আমি কিছু বিশ্বব্যাপী প্রসঙ্গ অবজেক্ট ভাগ করে, বা এমনকি অন্যান্য রেফারেন্স ধারণ করে এমন কোনও প্রসঙ্গ অবজেক্টটিও পাস করে বাই রেফারেন্সটি পারি? আমি এখনও পাস-বাই-মান, কিন্তু অন্তত আমি রেফারেন্স আমি এক্সেস আছে করতে পরিবর্তন করুন এবং অন্য কিছু তাদের বিন্দু আছে।
YoYo

1
@ সঞ্জীব: কল-বাই-অবজেক্ট-শেয়ারিং হ'ল পাস-বাই-ভ্যালুর একটি বিশেষ ঘটনা। তবে, অনেক লোক প্রবলভাবে তর্ক করে যে জাভা (এবং পাইথন, রুবি, ইসিএমএসক্রিপট, স্মলটালকের মতো অনুরূপ ভাষা) পাস-বাই-রেফারেন্স। আমি এটা পাস-বাই-মান, অত্যধিক ডাকতে পছন্দ করেন, কিন্তু কল-বাই-অবজেক্ট শেয়ারিং একটি যুক্তিসঙ্গত শব্দটি যে এমনকি যারা তর্ক এটা করা হয় যে মনে করা হয় না পাস-বাই-মান সম্মত করতে পারেন।
জার্গ ডব্লু মিত্তাগ

119

বিষয়ের মূল অংশ যে শব্দ রেফারেন্স অভিব্যক্তি মানে কিছু শব্দের স্বাভাবিক অর্থ থেকে সম্পূর্ণরূপে ভিন্ন "রেফারেন্স দ্বারা পাস" রেফারেন্স জাভা।

সাধারণত জাভা রেফারেন্সের অর্থ কোনও বস্তুর রে আ রেফারেন্স । তবে প্রযুক্তিগত পদগুলি প্রোগ্রামিং ভাষার তত্ত্ব থেকে রেফারেন্স / মান দ্বারা পাস করে মেমরি কোষের একটি রেফারেন্সের কথা বলছে যা ভেরিয়েবলটি ধারণ করে , যা সম্পূর্ণ আলাদা is


7
@ জিভর্গ - তারপরে "নুলপয়েন্টারএক্সসেপশন" কী?
হট লিকস

5
@ হট: জাভা পরিষ্কার পরিভাষায় স্থির হওয়ার আগে থেকে দুর্ভাগ্যক্রমে একটি নামযুক্ত ব্যতিক্রম। সি # তে শব্দার্থগত সমতুল্য ব্যতিক্রমকে নুলারফেরান এক্সেপশন বলে।
জ্যাকবিবি

4
আমার কাছে সর্বদা এটি মনে হয়েছিল যে জাভা পরিভাষায় "রেফারেন্স" এর ব্যবহার একটি প্রভাব যা বোঝার ক্ষেত্রে বাধা দেয়।
হট লিকস

আমি এইগুলিকে "অবজেক্টের কাছে হ্যান্ডেল" হিসাবে তথাকথিত "পয়েন্টারগুলিতে পয়েন্টার" বলতে শিখেছি। এতে অস্পষ্টতা কমেছে।
moronkreacionz

86

জাভাতে সবই রেফারেন্স হয়, সুতরাং আপনার যখন এমন কিছু থাকে: Point pnt1 = new Point(0,0);জাভা নিম্নলিখিতগুলি করেন:

  1. নতুন পয়েন্ট অবজেক্ট তৈরি করে
  2. নতুন পয়েন্ট রেফারেন্স তৈরি করে এবং পূর্ববর্তী পয়েন্ট পয়েন্ট অবজেক্টে পয়েন্টের ( রেফারেন্স ) রেফারেন্সটি আরম্ভ করুন।
  3. এখান থেকে পয়েন্ট অবজেক্ট লাইফের মাধ্যমে আপনি পিএনটি 1 রেফারেন্সের মাধ্যমে সেই অবজেক্টে অ্যাক্সেস করতে পারবেন। সুতরাং আমরা বলতে পারি যে জাভাতে আপনি এর রেফারেন্সের মাধ্যমে বস্তুটি ব্যবহার করেন।

এখানে চিত্র বর্ণনা লিখুন

জাভা রেফারেন্স দ্বারা পদ্ধতি আর্গুমেন্ট পাস না; এটি মান দ্বারা তাদের পাস। আমি এই সাইট থেকে উদাহরণ ব্যবহার করব :

public static void tricky(Point arg1, Point arg2) {
  arg1.x = 100;
  arg1.y = 100;
  Point temp = arg1;
  arg1 = arg2;
  arg2 = temp;
}
public static void main(String [] args) {
  Point pnt1 = new Point(0,0);
  Point pnt2 = new Point(0,0);
  System.out.println("X1: " + pnt1.x + " Y1: " +pnt1.y); 
  System.out.println("X2: " + pnt2.x + " Y2: " +pnt2.y);
  System.out.println(" ");
  tricky(pnt1,pnt2);
  System.out.println("X1: " + pnt1.x + " Y1:" + pnt1.y); 
  System.out.println("X2: " + pnt2.x + " Y2: " +pnt2.y);  
}

প্রোগ্রামের প্রবাহ:

Point pnt1 = new Point(0,0);
Point pnt2 = new Point(0,0);

দুটি পৃথক রেফারেন্স যুক্ত দুটি ভিন্ন পয়েন্ট অবজেক্ট তৈরি করা। এখানে চিত্র বর্ণনা লিখুন

System.out.println("X1: " + pnt1.x + " Y1: " +pnt1.y); 
System.out.println("X2: " + pnt2.x + " Y2: " +pnt2.y);
System.out.println(" ");

যেমন প্রত্যাশিত আউটপুট হবে:

X1: 0     Y1: 0
X2: 0     Y2: 0

এই লাইনে 'পাস-বাই-মান' খেলায় যায় ...

tricky(pnt1,pnt2);           public void tricky(Point arg1, Point arg2);

তথ্যসূত্র pnt1এবং pnt2করছে মান দ্বারা গৃহীত চতুর পদ্ধতি, যার মানে যে এখন পুলিশের রেফারেন্স pnt1এবং pnt2তাদের আছে copiesনামে arg1এবং arg2.So pnt1এবং arg1 পয়েন্ট একই বস্তু। (একই জন্য pnt2এবং arg2) এখানে চিত্র বর্ণনা লিখুন

ইন trickyপদ্ধতি:

 arg1.x = 100;
 arg1.y = 100;

এখানে চিত্র বর্ণনা লিখুন

trickyপদ্ধতিতে পরবর্তী

Point temp = arg1;
arg1 = arg2;
arg2 = temp;

এখানে, আপনি প্রথম নতুন তৈরি tempপয়েন্ট রেফারেন্স যা হবে বাতলান মত একই জায়গা arg1রেফারেন্স। তারপর আপনি রেফারেন্স সরাতে arg1করার বিন্দু মত একই জায়গায় arg2রেফারেন্স। শেষ পর্যন্ত একই জায়গায় নির্দেশarg2 করবে ।temp

এখানে চিত্র বর্ণনা লিখুন

এখান থেকে পরিধি trickyপদ্ধতি চলে গেছে এবং আপনি রেফারেন্স আর কোন অ্যাক্সেস নেই: arg1, arg2, tempতবে গুরুত্বপূর্ণ দ্রষ্টব্যটি হ'ল তারা যখন 'লাইফে' থাকে তখন এই রেফারেন্সগুলি দিয়ে আপনি যা কিছু করেন তা স্থায়ীভাবে সেই বস্তুকে প্রভাবিত করে যার দিকে তারা ইঙ্গিত করে।

সুতরাং কার্যকর পদ্ধতি প্রয়োগের পরে tricky, আপনি যখন ফিরে আসবেন তখন আপনার mainএই পরিস্থিতি রয়েছে: এখানে চিত্র বর্ণনা লিখুন

সুতরাং এখন, প্রোগ্রামের সম্পূর্ণ বাস্তবায়ন হবে:

X1: 0         Y1: 0
X2: 0         Y2: 0
X1: 100       Y1: 100
X2: 0         Y2: 0

7
জাভাতে যখন আপনি "জাভাতে সবই রেফারেন্স" বলছেন তখন আপনার অর্থ সমস্ত বস্তু রেফারেন্স দ্বারা পাস করা হয়েছে। প্রাথমিক তথ্য প্রকারগুলি রেফারেন্স দ্বারা পাস হয় না।
এরিক

আমি প্রধান পদ্ধতিতে অদলবদল মান মুদ্রণ করতে সক্ষম। ট্রাইকি পদ্ধতিতে নীচের বিবৃতিটি যুক্ত করুন arg1.x = 1; arg1.y = 1; arg2.x = 2; arg2.y = 2;, যেমনটি এখন পেন্ট 2 রিফ্রেন্স এবং আর্গ 2 ধরে এখন পিএনটি 1 রেফারেন্স ধরেছে, সুতরাং, এর মুদ্রণX1: 2 Y1: 2 X2: 1 Y2: 1
শহীদ গাফুর

85

জাভা সর্বদা মান দ্বারা পাস হয়, রেফারেন্স দ্বারা পাস হয় না

সবার আগে, আমাদের বুঝতে হবে যে মান দ্বারা পাস এবং রেফারেন্স দ্বারা পাস কী।

মান দ্বারা পাস করার অর্থ হ'ল আপনি যে প্যারামিটারের মানটি দিয়ে গেছেন তা স্মরণে একটি অনুলিপি তৈরি করছেন This এটি প্রকৃত প্যারামিটারের বিষয়বস্তুর অনুলিপি

রেফারেন্স দ্বারা পাস (যা ঠিকানা দ্বারা পাসও বলা হয়) এর অর্থ আসল প্যারামিটারের ঠিকানার একটি অনুলিপি সঞ্চয় করা হয়

কখনও কখনও জাভা রেফারেন্স দ্বারা পাস মায়া দিতে পারেন। নীচের উদাহরণটি ব্যবহার করে এটি কীভাবে কাজ করে তা দেখুন:

public class PassByValue {
    public static void main(String[] args) {
        Test t = new Test();
        t.name = "initialvalue";
        new PassByValue().changeValue(t);
        System.out.println(t.name);
    }

    public void changeValue(Test f) {
        f.name = "changevalue";
    }
}

class Test {
    String name;
}

এই প্রোগ্রামটির ফলাফল:

changevalue

আসুন ধাপে ধাপে:

Test t = new Test();

যেহেতু আমরা সবাই জানি এটি গাদা একটি বস্তু তৈরি করবে এবং রেফারেন্স মানটি টি তে ফিরিয়ে দেবে। উদাহরণস্বরূপ, ধরুন টি এর মানটি 0x100234(আমরা আসল জেভিএম অভ্যন্তরীণ মান জানি না, এটি কেবল একটি উদাহরণ)।

প্রথম চিত্র

new PassByValue().changeValue(t);

ফাংশনে রেফারেন্স টি পাস করার সময় এটি অবজেক্ট টেস্টের প্রকৃত রেফারেন্স মানটি সরাসরি পাস করবে না, তবে এটি টি এর একটি অনুলিপি তৈরি করবে এবং তারপরে এটি ফাংশনে পাস করবে। যেহেতু এটি মান দ্বারা পাস হচ্ছে , এটি এর আসল উল্লেখের পরিবর্তে ভেরিয়েবলের একটি অনুলিপি পাস করে। যেহেতু আমরা বলেছিলাম যে টির মান ছিল তাই 0x100234টি এবং এফ উভয়েরই একই মান থাকবে এবং তাই তারা একই বস্তুকে নির্দেশ করবে।

দ্বিতীয় উদাহরণ

আপনি যদি রেফারেন্স ব্যবহার করে ফাংশনে কোনও কিছু পরিবর্তন করেন তবে এটি অবজেক্টের বিদ্যমান সামগ্রীগুলিকে সংশোধন করবে। এজন্য আমরা আউটপুট পেয়েছি changevalueযা ফাংশনে আপডেট হয়।

এটি আরও স্পষ্টভাবে বুঝতে, নিম্নলিখিত উদাহরণটি বিবেচনা করুন:

public class PassByValue {
    public static void main(String[] args) {
        Test t = new Test();
        t.name = "initialvalue";
        new PassByValue().changeRefence(t);
        System.out.println(t.name);
    }

    public void changeRefence(Test f) {
        f = null;
    }
}

class Test {
    String name;
}

এই একটি নিক্ষেপ করবে NullPointerException? না, কারণ এটি কেবলমাত্র রেফারেন্সের একটি অনুলিপি পাস করে। রেফারেন্স দিয়ে যাওয়ার ক্ষেত্রে এটি NullPointerExceptionনীচে যেমনটি ছুঁড়ে ফেলতে পারে :

তৃতীয় দৃষ্টান্ত

আশা করি এটি সাহায্য করবে।


71

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

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

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

মূলত এটি কোনও ভাষাকে কোনও প্রতিনিধিত্ব না করেই রেফারেন্স প্রদান করা প্রযুক্তিগতভাবে অসম্ভব (যখন এটি তাত্ক্ষণিক মান হয়ে যায়)।

বলে দেয় আমরা একটি পরিবর্তনশীল ফু আছে, তার অবস্থান মেমরি 47th বাইট হয় এবং তার মূল্য 5. আমরা অন্য পরিবর্তনশীল আছে Ref2Foo যা মেমরি 223rd বাইট এ, এবং তার মান 47. হতে হবে এই Ref2Foo একটি প্রযুক্তিগত পরিবর্তনশীল হতে পারে , প্রোগ্রাম দ্বারা স্পষ্টভাবে তৈরি করা হয় নি। আপনি যদি অন্য কোনও তথ্য ছাড়াই 5 এবং 47 এর দিকে তাকান তবে আপনি কেবল দুটি মান দেখতে পাবেন । আপনি যদি সেগুলি রেফারেন্স হিসাবে ব্যবহার করেন তবে আমাদের পৌঁছাতে হবে 5:

(Name)[Location] -> [Value at the Location]
---------------------
(Ref2Foo)[223]  -> 47
(Foo)[47]       -> 5

জাম্প-টেবিলগুলি এভাবেই কাজ করে।

যদি আমরা Foo এর মান সহ কোনও পদ্ধতি / ফাংশন / পদ্ধতি কল করতে চাই তবে ভাষা এবং এর বিভিন্ন পদ্ধতির প্রার্থনা মোডের উপর নির্ভর করে পদ্ধতিতে ভেরিয়েবলটি পাস করার কয়েকটি সম্ভাব্য উপায় রয়েছে :

  1. 5 সিপিইউ নিবন্ধগুলির একটিতে অনুলিপি হয়ে যায় (অর্থাত্ EAX)।
  2. 5 স্ট্যাকের মধ্যে PUSHd পায়।
  3. 47 সিপিইউ নিবন্ধগুলির একটিতে অনুলিপি করা হয়
  4. 47 স্ট্যাকের দিকে ধাক্কা।
  5. 223 সিপিইউ নিবন্ধগুলির মধ্যে একটিতে অনুলিপি করা হয়।
  6. 223 স্ট্যাকের মধ্যে PUSHd পায়।

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

এখন আমরা পদ্ধতিতে ফু পাস করেছি:

  • যদি ১ এবং ২ এর ক্ষেত্রে আপনি Foo ( Foo = 9) পরিবর্তন করেন তবে এটি কেবল স্থানীয় সুযোগকেই প্রভাবিত করবে কারণ আপনার মানটির একটি অনুলিপি রয়েছে। পদ্ধতির অভ্যন্তর থেকে আমরা নির্ধারণ করতে পারি না মেমরিতে আসল ফু কোথায় ছিল।
  • ক্ষেত্রে ৩ এবং ৪. আপনি যদি ডিফল্ট ভাষা নির্মান এবং ফু ( Foo = 11) পরিবর্তন করেন তবে এটি বিশ্বব্যাপী ফু বদলাতে পারে (ভাষার উপর নির্ভর করে, যেমন জাভা বা পাস্কালের procedure findMin(x, y, z: integer;ভার এম: integer); ) like তবে যদি ভাষাটি আপনাকে ডিरेফার প্রক্রিয়াটি অবলম্বন করতে দেয় তবে আপনি 47বলতে পারেন 49। এই মুহুর্তে ফু পরিবর্তন করা হয়েছে যদি আপনি এটা পড়তে, কারণ আপনি পরিবর্তিত হয়েছে বলে মনে হয় স্থানীয় পয়েন্টার এটি। এবং যদি আপনি এই ফুটিকে পদ্ধতির অভ্যন্তরে পরিবর্তন করতে চান (তবে Foo = 12আপনি সম্ভবত প্রোগ্রামটি কার্যকর করতে পারেন) (যেমন। সেগফাল্ট) কারণ আপনি প্রত্যাশার চেয়ে আলাদা মেমরিতে লিখবেন, আপনি এমনকি এমন একটি অঞ্চলও পরিবর্তন করতে পারবেন যা নির্বাহযোগ্যকে ধরে রাখতে হবে প্রোগ্রাম এবং এতে লেখা চলমান কোডটি সংশোধন করবে (ফু এখন নেই 47)। তবে ফু এর মান47বিশ্বব্যাপী পরিবর্তন হয়নি, শুধুমাত্র পদ্ধতির অভ্যন্তরে, কারণ পদ্ধতিটির 47অনুলিপিও ছিল।
  • ক্ষেত্রে and এবং 6.. আপনি যদি 223পদ্ধতিটির অভ্যন্তরে পরিবর্তন করেন তবে এটি ৩ বা ৪ এর মতো একই মহাবিশ্ব তৈরি করে (একটি পয়েন্টার, এখনকার খারাপ মানের দিকে ইঙ্গিত করে, এটি আবার পয়েন্টার হিসাবে ব্যবহৃত হয়) তবে এটি এখনও স্থানীয় সমস্যা, যেমন 223 অনুলিপি করা হয়েছিল । তবে আপনি যদি অবনতি করতে সক্ষম হন Ref2Foo(এটি 223), নির্দেশিত মানটিতে পৌঁছাতে এবং সংশোধন করতে 47, বলুন 49, এটি বিশ্বব্যাপী ফুগুলিকে প্রভাবিত করবে , কারণ এই ক্ষেত্রে পদ্ধতিগুলি একটি অনুলিপি পেয়েছে 223 তবে রেফারেন্সটি 47কেবল একবারে উপস্থিত রয়েছে, এবং এটি পরিবর্তন করে থেকে 49যে নেতৃত্ব দেবেন Ref2Fooভুল মান ডাবল dereferencing।

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

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

সুতরাং সংক্ষেপে এবং জাভার নিজস্ব পরিভাষায় জাভা হ'ল পাস-বাই-ভ্যালু যেখানে মান হতে পারে: হয় আসল মান বা মান যা কোনও উল্লেখের প্রতিনিধিত্ব করে ।


1
পাস-রেফারেন্স সহ একটি ভাষায়, যে জিনিসটি পাস করা হয় (রেফারেন্স) তা সংক্ষিপ্ত; প্রাপক এটি অনুলিপি করার জন্য "অনুমিত" নয়। জাভাতে, একটি অ্যারে পাস করা হয় "অবজেক্ট আইডেন্টিফায়ার" - এটি কাগজের স্লিপের সমতুল্য যা "অবজেক্ট # 24601" বলে, যখন নির্মিত 24601 তম বস্তুটি অ্যারে ছিল। প্রাপক যে কোনও জায়গায় "অবজেক্ট # 24601" অনুলিপি করতে পারবেন এবং "অবজেক্ট # 24601" বলে কাগজের স্লিপ সহ যে কেউ অ্যারের উপাদানগুলির সাথে যা চান তা করতে পারেন। বিটগুলির যে প্যাটার্নটি পাস করা হয়েছে তা অবশ্যই "অবজেক্ট # 24601" বলবে না, তবে ...
সুপারক্যাট

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

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

আমি ভেবেছিলাম "@" অপারেটর স্ট্যান্ডার্ড পাস্কালের অংশ না, তবে একটি সাধারণ এক্সটেনশন হিসাবে প্রয়োগ করা হয়েছিল। এটি কি স্ট্যান্ডার্ডের অংশ? আমার বক্তব্যটি ছিল সত্যিকারের পাস-বাই-রেফ সহ একটি ভাষায়, এবং কোনও সাময়িক অবজেক্টের কোড হিসাবে কোনও অল্পকালীন পয়েন্টার তৈরি করার ক্ষমতা নেই, কোডটি যা মহাবিশ্বের যে কোনও জায়গায় অ্যারেটির একমাত্র রেফারেন্স ধরে রাখে, অ্যারে পাস করার আগে holds রেফারেন্স জানতে পারে যে প্রাপক "চিট" না করে এটি পরে কেবলমাত্র একমাত্র রেফারেন্স ধরে রাখবে। জাভাতে এটি
সম্পাদনের

... যা একটিকে AtomicReferenceএনপ্যাপুলেট করে এবং রেফারেন্সটি বা তার লক্ষ্যকে প্রকাশ করে না, তবে পরিবর্তে লক্ষ্যকে জিনিসগুলি করার পদ্ধতি অন্তর্ভুক্ত করে; একবার যে কোডটিতে বস্তুটি পাস করা হয়েছিল, তার পরে, AtomicReference[[তার স্রষ্টা সরাসরি রেফারেন্স রেখেছিলেন]] অবৈধ এবং বাতিল করতে হবে। এটি যথাযথ শব্দার্থবিজ্ঞান সরবরাহ করবে, তবে এটি ধীর এবং আটকানো হবে।
সুপারক্যাট

70

জাভা মান দ্বারা একটি কল

কিভাবে এটা কাজ করে

  • আপনি সর্বদা রেফারেন্সের মান বিটের একটি অনুলিপি পাস করেন!

  • যদি এটি কোনও আদিম ডেটা টাইপ থাকে তবে এই বিটগুলিতে আদিম তথ্য টাইপের মান থাকে, তাই আমরা যদি পদ্ধতির অভ্যন্তরে শিরোনামের মানটি পরিবর্তন করি তবে এটি বাইরের পরিবর্তনগুলি প্রতিফলিত করে না।

  • যদি আপনি এটা পছন্দ একটি বস্তু ডাটা টাইপ এর ) foo বিন্যাস foo বিন্যাস = নতুন foo বিন্যাস ( বস্তুর ঠিকানার এই ক্ষেত্রে কপিতে তারপরে ফাইলটিকে শর্টকাট মত পাস, ধরুন আমরা একটি টেক্সট ফাইল আছে abc.txtডেস্কটপ \: সি এবং অনুমান করা আমরা শর্টকাট করতে একই ফাইলটি সিটিতে রেখে দিন: ডেস্কটপ \ অ্যাবসি-শর্টকাট সুতরাং আপনি যখন সি: \ ডেস্কটপ \ abc.txt থেকে ফাইলটি অ্যাক্সেস করবেন এবং 'স্ট্যাক ওভারফ্লো' লিখবেন এবং ফাইলটি বন্ধ করুন এবং আবার আপনি শর্টকাট থেকে ফাইলটি খুলবেন তখন আপনি লিখুন 'প্রোগ্রামারদের শেখার জন্য বৃহত্তম অনলাইন সম্প্রদায়' তবে মোট ফাইল পরিবর্তন হবে 'প্রোগ্রামারদের শেখার জন্য স্ট্যাক ওভারফ্লো বৃহত্তম বৃহত্তম সম্প্রদায়'যার অর্থ আপনি যেখানে ফাইলটি খুলছেন সেখান থেকে কিছু আসে যায় না, প্রতিবারই আমরা একই ফাইলটি অ্যাক্সেস করছিলাম, এখানে আমরা ফু কে একটি ফাইল হিসাবে ধরে নিতে পারি এবং ধরে নিতে পারি যে foo 123hd7h এ সংরক্ষণ করা হয়েছে ( সি: \ ডেস্কটপ \ abc.txt এর মতো মূল ঠিকানা ) ঠিকানা এবং 234jdid ( সি এর মতো অনুলিপি করা ঠিকানা : \ ডেস্কটপ \ অ্যাবসি -শর্টকাট যা আসলে ভিতরে ফাইলের মূল ঠিকানা থাকে) .. তাই আরও ভাল বোঝার জন্য শর্টকাট ফাইল করুন এবং অনুভব করুন ..


66

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

কয়েকটি বিষয়:

  1. "রেফারেন্স" শব্দটি দুটি পৃথক অর্থ সহ একটি বোঝা। জাভাতে এটি সহজভাবে একটি পয়েন্টার অর্থ, তবে "পাস-বাই-রেফারেন্স" এর প্রসঙ্গে এর অর্থ মূল ভেরিয়েবলের একটি হ্যান্ডেল যা পাস হয়েছিল।
  2. জাভা হ'ল পাস-বাই-মান । জাভা সি এর অন্যান্য বংশধর (অন্যান্য ভাষার মধ্যে)। সি এর আগে বেশ কয়েকটি (তবে সমস্ত নয়) আগের ভাষা ফরটারান এবং কোবোল পিবিআরকে সমর্থন করেছিল, তবে সি তা করেনি। পিবিআর এই অন্যান্য ভাষাগুলি উপ-রুটিনগুলির মধ্যে পাস ভেরিয়েবলগুলিতে পরিবর্তন আনার অনুমতি দেয়। একই জিনিসটি সম্পাদনের জন্য (যেমন ফাংশনের অভ্যন্তরে ভেরিয়েবলের মান পরিবর্তন করা), সি প্রোগ্রামাররা পয়েন্টারগুলিকে ভেরিয়েবলগুলিতে ফাংশনে রূপান্তরিত করে। জাভা হিসাবে সি দ্বারা অনুপ্রাণিত ভাষাগুলি এই ধারণাটি ধার করে এবং সি হিসাবে পদ্ধতিগুলিতে পয়েন্টারটি প্রদান অবিরত করে, জাভা তার পয়েন্টারগুলিকে রেফারেন্স বলে except আবার এটি "পাস-বাই-রেফারেন্স" এর চেয়ে "রেফারেন্স" শব্দের আলাদা ব্যবহার।
  3. সি ++ "&" অক্ষর ব্যবহার করে একটি রেফারেন্স প্যারামিটার ঘোষণার মাধ্যমে পাস-বাই-রেফারেন্সের অনুমতি দেয় (যা সি এবং সি ++ উভয় "ভেরিয়েবলের ঠিকানা" নির্দেশ করতে একই অক্ষর হিসাবে ব্যবহৃত হয়)। উদাহরণস্বরূপ, যদি আমরা রেফারেন্স দ্বারা একটি পয়েন্টারে পাস করি, প্যারামিটার এবং আর্গুমেন্ট কেবল একই বস্তুর দিকে নির্দেশ করছে না। বরং তারা একই পরিবর্তনশীল। কেউ যদি অন্য কোনও ঠিকানায় বা নথিতে সেট হয়ে যায়, অন্যটিও তাই করে।
  4. নীচের সি ++ উদাহরণে আমি রেফারেন্স দ্বারা একটি নাল টার্মিনেটেড স্ট্রিংয়ে একটি পয়েন্টারটি দিচ্ছি । এবং নীচের জাভা উদাহরণে আমি একটি স্ট্রিংয়ের কাছে জাভা রেফারেন্সটি দিয়ে যাচ্ছি (আবার, স্ট্রিংয়ের পয়েন্টারের সমান) মান অনুসারে। মন্তব্যগুলিতে আউটপুটটি লক্ষ্য করুন।

সি ++ রেফারেন্স উদাহরণ দিয়ে পাস:

using namespace std;
#include <iostream>

void change (char *&str){   // the '&' makes this a reference parameter
    str = NULL;
}

int main()
{
    char *str = "not Null";
    change(str);
    cout<<"str is " << str;      // ==>str is <null>
}

জাভা মান উদাহরণ দ্বারা "একটি জাভা রেফারেন্স" পাস

public class ValueDemo{

    public void change (String str){
        str = null;
    }

     public static void main(String []args){
        ValueDemo vd = new ValueDemo();
        String str = "not null";
        vd.change(str);
        System.out.println("str is " + str);    // ==> str is not null!!
                                                // Note that if "str" was
                                                // passed-by-reference, it
                                                // WOULD BE NULL after the
                                                // call to change().
     }
}

সম্পাদনা

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

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

program passByRefDemo;
type 
   iptr = ^integer;
var
   ptr: iptr;

   procedure setToNil(var ptr : iptr);
   begin
       ptr := nil;
   end;

begin
   new(ptr);
   ptr^ := 10;
   setToNil(ptr);
   if (ptr = nil) then
       writeln('ptr seems to be nil');     { ptr should be nil, so this line will run. }
end.

সম্পাদনা 2

কেন আর্নল্ড, জেমস গোসলিং (জাভা আবিষ্কার করেছেন এমন লোক) এবং ডেভিড হোমস, অধ্যায় ২, বিভাগ ২.6.৫ এর "দ্য জাভা প্রোগ্রামিং ল্যাঙ্গুয়েজ" এর কিছু অংশ

পদ্ধতিতে সমস্ত পরামিতি "মান দ্বারা" পাস করা হয় । অন্য কথায়, কোনও পদ্ধতিতে প্যারামিটার ভেরিয়েবলের মানগুলি আর্গুমেন্ট হিসাবে উল্লিখিত চালকের অনুলিপি হয়।

তিনি অবজেক্ট সম্পর্কে একই পয়েন্ট তৈরি করতে চলেছেন। । ।

আপনি সচেতন থাকা আবশ্যক যে যখন পরামিতি একটি বস্তু রেফারেন্স, এটা অবজেক্ট রেফারেন্স নয় বস্তুর নিজেই-যে হয় "মান দ্বারা" পাস

এবং একই বিভাগের শেষের দিকে তিনি জাভা সম্পর্কে কেবল একটি মূল্য দিয়ে পাস এবং কখনও রেফারেন্স দ্বারা পাস না হওয়া সম্পর্কে একটি বিস্তৃত বিবৃতি দেন।

জাভা প্রোগ্রামিংয়ের ভাষা রেফারেন্স দ্বারা অবজেক্টগুলি পাস করে না; এটি মান দ্বারা অবজেক্ট রেফারেন্স পাস করে । একই রেফারেন্সের দুটি অনুলিপি একই প্রকৃত অবজেক্টকে বোঝায়, একটি রেফারেন্স ভেরিয়েবলের মাধ্যমে করা পরিবর্তনগুলি অন্যটির মাধ্যমে দৃশ্যমান। ঠিক একটি প্যারামিটার পাসিং মোড আছে - মান অনুসারে পাস করুন এবং জিনিসগুলি সহজ রাখতে সহায়তা করে।

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

আমি মনে করি দুটি মডেলের মধ্যে পার্থক্যটি খুব সূক্ষ্ম এবং যদি আপনি প্রোগ্রামিং না করেন যেখানে আপনি যেখানে পাস-বাই-রেফারেন্সটি ব্যবহার করেছেন, এটি সহজেই মিস করা যায় যেখানে দুটি মডেলের পার্থক্য রয়েছে।

আমি আশা করি এটি বিতর্ক নিষ্পত্তি করে তবে সম্ভবত তা হবে না।

সম্পাদনা 3

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

কেবল জাভা বিকাশকারীদেরই এটি নিয়ে সমস্যা রয়েছে। তারা "রেফারেন্স" শব্দটির দিকে তাকিয়ে থাকে এবং তারা মনে করে যে এর অর্থটি ঠিক কী তারা জানে তাই তারা বিরোধী যুক্তি বিবেচনা করতেও বিরক্ত করে না।

যাইহোক, আমি একটি পুরানো পোস্টে একটি মন্তব্য লক্ষ্য করেছি, এটি একটি বেলুন সাদৃশ্য তৈরি করেছে যা আমি সত্যিই পছন্দ করেছি। এতটা যে আমি পয়েন্টটি চিত্রিত করার জন্য কার্টুনগুলির একটি সেট তৈরি করতে কিছু ক্লিপ-আর্ট একসাথে আঠালো করার সিদ্ধান্ত নিয়েছি।

মান দ্বারা একটি রেফারেন্স পাস করা - রেফারেন্সের পরিবর্তনগুলি কলারের সুযোগগুলিতে প্রতিফলিত হয় না, তবে অবজেক্টের পরিবর্তনগুলি। এটি কারণ রেফারেন্স অনুলিপি করা হয়েছে, তবে মূল এবং অনুলিপি উভয়ই একই বস্তুকে উল্লেখ করে। মান দ্বারা অবজেক্ট রেফারেন্স পাস করা

রেফারেন্স দ্বারা পাস - রেফারেন্সের কোন অনুলিপি নেই। একক রেফারেন্স কলার এবং কল করা ফাংশন উভয় দ্বারা ভাগ করা হয়। রেফারেন্সে বা অবজেক্টের ডেটার কোনও পরিবর্তনই কলারের সুযোগগুলিতে প্রতিফলিত হয়। রেফারেন্স দ্বারা পাস

সম্পাদনা 4

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

যখন পদ্ধতি বা কনস্ট্রাক্টরটি আহ্বান করা হয় (.115.12), আসল আর্গুমেন্ট এক্সপ্রেশনগুলির মানগুলি পদ্ধতি বা কনস্ট্রাক্টরের শরীরের নির্বাহের আগে নতুনভাবে তৈরি প্যারামিটার ভেরিয়েবলগুলি শুরু করে। ডিক্লেয়ারআইডে প্রদর্শিত আইডেন্টিফায়ারটি আনুষ্ঠানিক প্যারামিটারটি উল্লেখ করার জন্য পদ্ধতি বা কনস্ট্রাক্টরের শরীরে সাধারণ নাম হিসাবে ব্যবহার করা যেতে পারে।

যার অর্থ, জাভা কোনও পদ্ধতি চালানোর আগে পাস হওয়া প্যারামিটারগুলির একটি অনুলিপি তৈরি করে। অধিকাংশ লোক যারা কলেজে কম্পাইলার চর্চিত ভালো লেগেছে, আমি ব্যবহৃত "ড্রাগন বই" যা কম্পাইলার বই। এটি অধ্যায় 1-এ "কল-বাই-মান" এবং "কল-বাই-রেফারেন্স" এর একটি ভাল বর্ণনা রয়েছে The

নব্বইয়ের দশকে সংকলক-অধ্যয়নকালে আমি 1986 সাল থেকে বইটির প্রথম সংস্করণটি ব্যবহার করেছি যা জাভা প্রায় 9 বা 10 বছর পূর্বে তৈরি হয়েছিল। যাইহোক, আমি শুধু একটি কপি জুড়ে দৌড়ে 2nd Eddition 2007 থেকে যা আসলে জাভা উল্লেখ! বিভাগের ১.6..6 লেবেলযুক্ত "প্যারামিটার পাসিং মেকানিজম" প্যারামিটারটিকে সুন্দরভাবে পাস করার বর্ণনা দিয়েছে। "কল-বাই-মান" শিরোনামের নীচে একটি অংশ এখানে জাভা উল্লেখ করেছে:

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


4
সত্যিই, আপনি জাভা কেবল আদিম ধরণের জন্য মান দ্বারা পাস বলে এই উত্তরটি সহজ করতে পারেন। অবজেক্টের উত্তরাধিকার হিসাবে প্রাপ্ত সমস্ত কিছুই কার্যকরভাবে রেফারেন্সের মাধ্যমে পাস হয়, যেখানে রেফারেন্সটি আপনি যে পয়েন্টারটি দিয়ে যাচ্ছেন তা।
স্কুবা স্টিভ

1
@ জুয়ানমেন্ডেস, আমি কেবল উদাহরণ হিসাবে সি ++ ব্যবহার করেছি; আমি আপনাকে অন্যান্য ভাষায় উদাহরণ দিতে পারি। "রেফারেন্স দ্বারা পাস" শব্দটি C ++ এর অস্তিত্বের অনেক আগে থেকেই ছিল। এটি একটি খুব নির্দিষ্ট সংজ্ঞা সহ একটি পাঠ্যপুস্তক শব্দ। এবং সংজ্ঞা অনুসারে, জাভা রেফারেন্স দ্বারা পাস হয় না। আপনি চাইলে এই শব্দটি ব্যবহার করতে পারেন তবে আপনার ব্যবহারটি পাঠ্যপুস্তকের সংজ্ঞার সাথে সামঞ্জস্যপূর্ণ হবে না। এটি কেবল কোনও পয়েন্টারের কাছে নির্দেশক নয়। "পাস বাই রেফারেন্স" এর অনুমতি দেওয়ার জন্য এটি ভাষা দ্বারা নির্মিত একটি নির্মাণ। দয়া করে আমার উদাহরণটি নিবিড়ভাবে দেখুন তবে দয়া করে আমার শব্দটি এটির জন্য নেবেন না এবং এটি নিজের জন্য সন্ধান করুন।
সানজিভ

2
@ অটোমেটেড মাইকে আমি মনে করি যে "পাস-বাই-রেফারেন্স" হিসাবে জাভা বর্ণনা করাও বিভ্রান্তিমূলক, তাদের রেফারেন্স পয়েন্টার ছাড়া আর কিছুই নয়। সঞ্জীব যেমন মূল্য লিখেছিলেন, রেফারেন্স এবং পয়েন্টারটি পাঠ্যপুস্তকের শর্তাদি যা জাভা নির্মাতারা কী ব্যবহার করেন তা বিবেচনা না করেই তাদের নিজস্ব অর্থ রয়েছে।
Jrdrzej দুডকিউইচ

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

1
কী দুর্দান্ত উত্তর, "পাস বাই রেফারেন্স" জাভাতে উপস্থিত নেই (এবং জেএসের মতো অন্যান্য ভাষাগুলি)।
নিউফোল্ডার

56

যতদূর আমি জানি, জাভা কেবল কল দ্বারা মানকে জানে। এর অর্থ আদিম ডেটাটাইপগুলির জন্য আপনি একটি অনুলিপি এবং অবজেক্টগুলির জন্য আপনি অবজেক্টগুলির রেফারেন্সের একটি অনুলিপি সহ কাজ করবেন। তবে আমি মনে করি কিছু ক্ষতি আছে; উদাহরণস্বরূপ, এটি কাজ করবে না:

public static void swap(StringBuffer s1, StringBuffer s2) {
    StringBuffer temp = s1;
    s1 = s2;
    s2 = temp;
}


public static void main(String[] args) {
    StringBuffer s1 = new StringBuffer("Hello");
    StringBuffer s2 = new StringBuffer("World");
    swap(s1, s2);
    System.out.println(s1);
    System.out.println(s2);
}

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

public static void appendWorld(StringBuffer s1) {
    s1.append(" World");
}

public static void main(String[] args) {
    StringBuffer s = new StringBuffer("Hello");
    appendWorld(s);
    System.out.println(s);
}

এটি কমান্ড লাইনে হ্যালো ওয়ার্ল্ডকে জনপ্রিয় করবে। আপনি যদি স্ট্রিংবাফারকে স্ট্রিংয়ে পরিবর্তন করেন তবে এটি ঠিক হ্যালো উত্পন্ন করবে কারণ স্ট্রিং স্থায়ী নয়। উদাহরণ স্বরূপ:

public static void appendWorld(String s){
    s = s+" World";
}

public static void main(String[] args) {
    String s = new String("Hello");
    appendWorld(s);
    System.out.println(s);
}

তবে আপনি স্ট্রিংয়ের জন্য এমন একটি মোড়ক তৈরি করতে পারেন যা স্ট্রিংসের সাহায্যে এটি সক্ষম করে তুলবে:

class StringWrapper {
    public String value;

    public StringWrapper(String value) {
        this.value = value;
    }
}

public static void appendWorld(StringWrapper s){
    s.value = s.value +" World";
}

public static void main(String[] args) {
    StringWrapper s = new StringWrapper("Hello");
    appendWorld(s);
    System.out.println(s.value);
}

সম্পাদনা: আমি বিশ্বাস করি যে স্ট্রিংবাফারটি যখন দুটি স্ট্রিং "যুক্ত" করার কথা আসে তখন এটি ব্যবহার করার কারণ কারণ আপনি যে স্ট্রিংয়ের মতো অপরিবর্তনীয় অবজেক্টের সাহায্যে না করতে পারেন সেই আসল বস্তুটি সংশোধন করতে পারেন।


অদলবদলের পরীক্ষার জন্য +1 - রেফারেন্স দ্বারা পাস করা এবং মান দ্বারা রেফারেন্স পাস করার মধ্যে পার্থক্য করার জন্য সম্ভবত সবচেয়ে সোজা এবং রিলেটেবল উপায় । Iff আপনি সহজেই একটি ফাংশন লিখতে পারেন (1) অদলবদল যে এবং আহ্বানকারী এর অপেশাদার থেকে, (2) টাইপ অ্যাগনোস্টিক ততটাই যে স্ট্যাটিক টাইপিং পারবেন হয় (অন্য ধরনের সঙ্গে এটি ব্যবহার, যার অর্থ এর ঘোষিত ধরনের পরিবর্তন ছাড়া আর কিছুই প্রয়োজন এবং ) , এবং (3) কলারের স্পষ্টভাবে কোনও পয়েন্টার বা নাম পাস করার প্রয়োজন হয় না, তবে ভাষাটি রেফারেন্স দিয়ে পাসিং সমর্থন করে। swap(a, b)abab
সিএইচও

".. আদিম ডেটাটাইপগুলির জন্য আপনি একটি অনুলিপি নিয়ে কাজ করবেন এবং অবজেক্টের জন্য আপনি অবজেক্টগুলির রেফারেন্সের একটি অনুলিপি নিয়ে কাজ করবেন" - নিখুঁতভাবে লেখা!
রাউল

55

না, এটি রেফারেন্স দ্বারা পাস হয় না।

জাভা জাভা ভাষা নির্দিষ্টকরণ অনুসারে মান দ্বারা পাস করা হয়:

যখন পদ্ধতি বা কনস্ট্রাক্টরটি আহ্বান করা হয় (§15.12), আসল আর্গুমেন্ট এক্সপ্রেশনগুলির মানগুলি পদ্ধতি বা কনস্ট্রাক্টরের শরীরের নির্বাহের আগে নতুনভাবে তৈরি প্যারামিটার ভেরিয়েবলগুলিকে আরম্ভ করে । ডিক্লেয়ারআইডে প্রদর্শিত আইডেন্টিফায়ারটি আনুষ্ঠানিক প্যারামিটারটি উল্লেখ করার জন্য পদ্ধতি বা কনস্ট্রাক্টরের শরীরে সাধারণ নাম হিসাবে ব্যবহার করা যেতে পারে ।


52

চারটি উদাহরণের সাহায্যে আমার বোঝার ব্যাখ্যা করার চেষ্টা করি। জাভা হ'ল পাস-বাই-মান, এবং পাস-বাই-রেফারেন্স নয়

/ **

মান দ্বারা পাস

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

* /

উদাহরণ 1:

public class PassByValueString {
    public static void main(String[] args) {
        new PassByValueString().caller();
    }

    public void caller() {
        String value = "Nikhil";
        boolean valueflag = false;
        String output = method(value, valueflag);
        /*
         * 'output' is insignificant in this example. we are more interested in
         * 'value' and 'valueflag'
         */
        System.out.println("output : " + output);
        System.out.println("value : " + value);
        System.out.println("valueflag : " + valueflag);

    }

    public String method(String value, boolean valueflag) {
        value = "Anand";
        valueflag = true;
        return "output";
    }
}

ফলাফল

output : output
value : Nikhil
valueflag : false

উদাহরণ 2:

/ ** * * মূল্য দিয়ে পাস করুন * * /

public class PassByValueNewString {
    public static void main(String[] args) {
        new PassByValueNewString().caller();
    }

    public void caller() {
        String value = new String("Nikhil");
        boolean valueflag = false;
        String output = method(value, valueflag);
        /*
         * 'output' is insignificant in this example. we are more interested in
         * 'value' and 'valueflag'
         */
        System.out.println("output : " + output);
        System.out.println("value : " + value);
        System.out.println("valueflag : " + valueflag);

    }

    public String method(String value, boolean valueflag) {
        value = "Anand";
        valueflag = true;
        return "output";
    }
}

ফলাফল

output : output
value : Nikhil
valueflag : false

উদাহরণ 3:

/ ** এই 'পাস বাই ভ্যালুতে' পাস বাই রেফারেন্সের অনুভূতি রয়েছে

কিছু লোক বলে যে আদিম ধরণের এবং 'স্ট্রিং' হ'ল 'মান দ্বারা পাস' এবং অবজেক্টগুলি 'রেফারেন্স দ্বারা পাস'।

তবে এই উদাহরণ থেকে, আমরা বুঝতে পারি যে এটি কেবলমাত্র মূল্য দ্বারা পাস হয়, মনে রাখবেন যে এখানে আমরা মান হিসাবে রেফারেন্সটি পাস করছি। অর্থাত: রেফারেন্সটি মান দ্বারা পাস হয়। যে কারণে পরিবর্তন করতে সক্ষম এবং এখনও স্থানীয় সুযোগের পরে এটি সত্য true তবে আমরা আসল রেফারেন্সটি মূল ক্ষেত্রের বাইরে পরিবর্তন করতে পারি না। এর অর্থ কী PassByValueObjectCase2 এর পরবর্তী উদাহরণ দ্বারা প্রদর্শিত হয়।

* /

public class PassByValueObjectCase1 {

    private class Student {
        int id;
        String name;
        public Student() {
        }
        public Student(int id, String name) {
            super();
            this.id = id;
            this.name = name;
        }
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public String toString() {
            return "Student [id=" + id + ", name=" + name + "]";
        }
    }

    public static void main(String[] args) {
        new PassByValueObjectCase1().caller();
    }

    public void caller() {
        Student student = new Student(10, "Nikhil");
        String output = method(student);
        /*
         * 'output' is insignificant in this example. we are more interested in
         * 'student'
         */
        System.out.println("output : " + output);
        System.out.println("student : " + student);
    }

    public String method(Student student) {
        student.setName("Anand");
        return "output";
    }
}

ফলাফল

output : output
student : Student [id=10, name=Anand]

উদাহরণ 4:

/ **

উদাহরণ 3 (PassByValueObjectCase1.java) এ যা উল্লেখ করা হয়েছিল তা ছাড়াও আমরা আসল রেফারেন্সটি মূল ক্ষেত্রের বাইরে পরিবর্তন করতে পারি না। "

দ্রষ্টব্য: আমি কোডটি আটকাইচ্ছি না private class Student। শ্রেণীর সংজ্ঞা Studentউদাহরণ 3 এর মতোই।

* /

public class PassByValueObjectCase2 {

    public static void main(String[] args) {
        new PassByValueObjectCase2().caller();
    }

    public void caller() {
        // student has the actual reference to a Student object created
        // can we change this actual reference outside the local scope? Let's see
        Student student = new Student(10, "Nikhil");
        String output = method(student);
        /*
         * 'output' is insignificant in this example. we are more interested in
         * 'student'
         */
        System.out.println("output : " + output);
        System.out.println("student : " + student); // Will it print Nikhil or Anand?
    }

    public String method(Student student) {
        student = new Student(20, "Anand");
        return "output";
    }

}

ফলাফল

output : output
student : Student [id=10, name=Nikhil]

49

আপনি কখনই জাভাতে রেফারেন্স দিয়ে যেতে পারবেন না এবং আপনি যখন কোনও মেথড কল থেকে একাধিক মান ফিরিয়ে দিতে চান তখন সেই উপায়গুলির মধ্যে একটি যা স্পষ্ট। সি ++ এ নিম্নলিখিত বিট কোডটি বিবেচনা করুন:

void getValues(int& arg1, int& arg2) {
    arg1 = 1;
    arg2 = 2;
}
void caller() {
    int x;
    int y;
    getValues(x, y);
    cout << "Result: " << x << " " << y << endl;
}

কখনও কখনও আপনি জাভাতে একই প্যাটার্নটি ব্যবহার করতে চান, তবে আপনি পারবেন না; অন্তত সরাসরি না পরিবর্তে আপনি এই জাতীয় কিছু করতে পারেন:

void getValues(int[] arg1, int[] arg2) {
    arg1[0] = 1;
    arg2[0] = 2;
}
void caller() {
    int[] x = new int[1];
    int[] y = new int[1];
    getValues(x, y);
    System.out.println("Result: " + x[0] + " " + y[0]);
}

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


48

আমি ভেবেছিলাম স্পেসিফিকেশন থেকে আরও বিশদ যুক্ত করতে আমি এই উত্তরটির অবদান রাখব।

প্রথমত, রেফারেন্স দ্বারা পাসের তুলনায় পার্থক্য কী? মান দ্বারা পাস করা?

রেফারেন্স দিয়ে পাস করার অর্থ হ'ল ডাকা ফাংশনগুলির পরামিতি কলকারীদের পাস হওয়া যুক্তির মতো হবে (মান নয়, তবে পরিচয়টি - নিজেই ভেরিয়েবল)।

মান দ্বারা পাস মানে কলযুক্ত ফাংশনগুলির পরামিতি কলকারীদের পাস হওয়া যুক্তির অনুলিপি হবে।

অথবা উইকিপিডিয়া থেকে, পাস-বাই-রেফারেন্স প্রসঙ্গে

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

এবং পাস-বাই-ভ্যালু বিষয়ে

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

দ্বিতীয়ত, আমাদের জানতে হবে জাভা এর পদ্ধতির ডাকে কী ব্যবহার করে। জাভা ল্যাঙ্গুয়েজ স্পেসিফিকেশন রাজ্যের

যখন পদ্ধতি বা কনস্ট্রাক্টরটি আহ্বান করা হয় (§15.12), আসল আর্গুমেন্ট এক্সপ্রেশনগুলির মানগুলি পদ্ধতি বা কনস্ট্রাক্টরের শরীরের নির্বাহের আগে নতুনভাবে তৈরি প্যারামিটার ভেরিয়েবলগুলিকে আরম্ভ করে

সুতরাং এটি যুক্ত প্যারামিটার ভেরিয়েবলের সাথে যুক্তির মান নির্ধারণ করে (বা বাঁধাই করে)।

তর্কের মান কী?

আসুন রেফারেন্সের ধরণগুলি বিবেচনা করুন, জাভা ভার্চুয়াল মেশিনের স্পেসিফিকেশন স্টেটস

এখানে তিন ধরণের রেফারেন্স রয়েছে : শ্রেণির ধরণ, অ্যারে প্রকার এবং ইন্টারফেস প্রকার। তাদের মানগুলি যথাক্রমে গতিশীলভাবে তৈরি শ্রেণীর উদাহরণ, অ্যারে বা শ্রেণীর দৃষ্টান্ত বা ইন্টারেফেস প্রয়োগ করে এমন অ্যারেগুলির উল্লেখ।

জাভা ল্যাঙ্গুয়েজ স্পেসিফিকেশন আরো বলেন

রেফারেন্স মান (প্রায়শই কেবল রেফারেন্স) হ'ল এই অবজেক্টের পয়েন্টার এবং একটি বিশেষ নাল রেফারেন্স, যা কোনও অবজেক্টকে বোঝায় না।

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

সুতরাং

public void method (String param) {}
...
String var = new String("ref");
method(var);
method(var.toString());
method(new String("ref"));

সমস্ত Stringপদ্ধতির সদ্য নির্মিত প্যারামিটারে কোনও উদাহরণের জন্য একটি রেফারেন্সের মান আবদ্ধ করে param। পাস-বাই-ভ্যালু সংজ্ঞাটি ঠিক এটিই বর্ণনা করে। যেমন, জাভা হচ্ছে পাস-বাই-ভ্যালু

আপনি কোনও পদ্ধতির জন্য অনুরোধ করতে বা রেফারেন্সযুক্ত বস্তুর কোনও ক্ষেত্র অ্যাক্সেস করতে রেফারেন্সটি অনুসরণ করতে পারেন তা এই কথোপকথনের সাথে সম্পূর্ণ অপ্রাসঙ্গিক। পাস বাই রেফারেন্স সংজ্ঞা ছিল

এর সাধারণ অর্থ হ'ল ফাংশনটি আর্গুমেন্ট হিসাবে ব্যবহৃত ভেরিয়েবলটি সংশোধন করতে পারে (অর্থাত্ নির্ধারণ করতে পারে — এমন কিছু যা তার কলকারী দ্বারা দেখা যাবে।

জাভাতে, ভেরিয়েবলটি সংশোধন করার অর্থ এটি পুনরায় অর্পণ করা। জাভাতে, আপনি যদি পদ্ধতিটির মধ্যে পরিবর্তনশীলটিকে পুনরায় স্বাক্ষর করেন তবে এটি কলারের নজরে আসবে না। ভেরিয়েবল দ্বারা রেফারেন্স করা অবজেক্টটি পরিবর্তন করা সম্পূর্ণ ভিন্ন ধারণা।


আদিম মান এছাড়াও জাভা ভার্চুয়াল মেশিন নির্দিষ্টকরণ মধ্যে সংজ্ঞায়িত করা হয় এখানে । প্রকারের মানটি যথাযথভাবে এনকোডযুক্ত (8, 16, 32, 64, ইত্যাদি বিট) সম্পর্কিত অবিচ্ছেদ্য বা ভাসমান পয়েন্ট মান।


42

জাভাতে কেবল রেফারেন্সগুলি পাস হয় এবং মান দ্বারা পাস হয়:

জাভা আর্গুমেন্টগুলি সমস্ত মান দ্বারা পাস করা হয় (পদ্ধতিটি ব্যবহার করার সময় রেফারেন্সটি অনুলিপি করা হয়):

আদিম ধরণের ক্ষেত্রে জাভা আচরণটি সহজ: মানটি আদিম ধরণের অন্য একটি উদাহরণে অনুলিপি করা হয়।

অবজেক্টের ক্ষেত্রে এটি একই: অবজেক্ট ভেরিয়েবলগুলি পয়েন্টার (বালতি) হ'ল কেবলমাত্র অবজেক্টের ঠিকানা যা "নতুন" কীওয়ার্ড ব্যবহার করে তৈরি করা হয়েছিল, এবং আদিম ধরণের মতো অনুলিপি করা হয়।

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

"স্ট্রিং" অবজেক্টগুলি শহুরে কিংবদন্তির পক্ষে উত্তম উদাহরণ হিসাবে উপস্থিত বলে মনে হচ্ছে যে "অবজেক্টগুলি রেফারেন্স দ্বারা পাস করা হয়েছে":

বাস্তবে, কোনও পদ্ধতি ব্যবহার করে আপনি কখনই সক্ষম হবেন না, যুক্তি হিসাবে পাস করা স্ট্রিংয়ের মান আপডেট করতে:

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


সুতরাং এটি বস্তুগুলির ক্ষেত্রে বাইফুল এবং আদিমদের ক্ষেত্রে বাইভাল?
মোक्स

@ মোক্স দয়া করে পড়ুন: অবজেক্টগুলি রেফারেন্স দ্বারা পাস করা হয় না, এটি একটি নেতৃত্বশাস্ত্র: স্ট্রিং এ = নতুন স্ট্রিং ("অপরিবর্তিত");
ব্যবহারকারী 1767316

1
অ্যারন "রেফারেন্স দ্বারা পাস" এর অর্থ এই নয় যে "জাভাতে 'রেফারেন্স' নামে পরিচিত এমন ধরণের একটি সদস্যকে এমন একটি মান পাস করুন"। "রেফারেন্স" এর দুটি ব্যবহারের অর্থ ভিন্ন জিনিস।
ফিলিপ্সি

2
বেশ বিভ্রান্তিকর উত্তর। আপনি কোনও পদ্ধতিতে স্ট্রিং অবজেক্ট পরিবর্তন করতে না পারার কারণ, যা রেফারেন্স দ্বারা পাস করা হয় তা হ'ল স্ট্রিং অবজেক্টগুলি ডিজাইনের মাধ্যমে অপরিবর্তনীয় এবং আপনি পছন্দ মতো কাজ করতে পারবেন না strParam.setChar ( i, newValue )। এটি বলেছিল যে স্ট্রিংগুলি অন্য কোনও কিছুর মতোই মান দিয়ে যায় এবং স্ট্রিং যেহেতু স্ট্রিং একটি আদিম প্রকার, তাই সেই মানটি সেই জিনিসটির সাথে সম্পর্কিত যা নতুন দিয়ে তৈরি হয়েছিল এবং আপনি স্ট্রিং.ইনটার্ন () ব্যবহার করে এটি পরীক্ষা করতে পারেন ।
zakmck

1
পরিবর্তে, আপনি প্যারাম = "অন্য স্ট্রিং" (নতুন স্ট্রিংয়ের সমান ("অন্য স্ট্রিং")) এর মাধ্যমে স্ট্রিং পরিবর্তন করতে পারবেন না কারণ প্যারামের রেফারেন্স মান (যা এখন "অন্য স্ট্রিংকে" নির্দেশ করে) পদ্ধতির থেকে ফিরে আসতে পারে না শরীর। তবে অন্য যে কোনও অবজেক্টের ক্ষেত্রে এটি সত্য, পার্থক্যটি হ'ল যখন ক্লাস ইন্টারফেস এটির জন্য অনুমতি দেয় আপনি প্যারাম.changeMe () করতে পারেন এবং শীর্ষ স্তরের অবজেক্টটি পরিবর্তিত হবে কারণ প্যারাম এটিকে নির্দেশ করছে, প্যারামের রেফারেন্স মানটি সত্ত্বেও (সম্বোধন করা অবস্থান, সি পদে) পদ্ধতি থেকে পপ আপ করতে পারবেন না।
zakmck

39

পার্থক্য, বা সম্ভবত যেভাবে আমি মনে করি মূল পোস্টারের মতো একই ইমপ্রেসের অধীনে থাকতাম তা হ'ল: জাভা সর্বদা মান দ্বারা পাস হয়। জাভাতে সমস্ত বস্তু (জাভাতে, আদিম বাদে কিছু) রেফারেন্স। এই উল্লেখগুলি মান দ্বারা পাস করা হয় are


2
আমি আপনার দ্বিতীয় থেকে শেষ বাক্যটি খুব বিভ্রান্তিকর মনে করি। এটি সত্য নয় যে "জাভাতে থাকা সমস্ত বস্তুর উল্লেখ" "। এটি শুধুমাত্র রেফারেন্স সেই বস্তু যা রেফারেন্স হয়।
দাউদ ইবনে কেরেম

37

অনেক লোক এর আগে যেমন উল্লেখ করেছে, জাভা সর্বদা পাস-বাই-মান হয়

এখানে আরেকটি উদাহরণ যা আপনাকে পার্থক্যটি বুঝতে সহায়তা করবে ( ক্লাসিক অদলবদলের উদাহরণ ):

public class Test {
  public static void main(String[] args) {
    Integer a = new Integer(2);
    Integer b = new Integer(3);
    System.out.println("Before: a = " + a + ", b = " + b);
    swap(a,b);
    System.out.println("After: a = " + a + ", b = " + b);
  }

  public static swap(Integer iA, Integer iB) {
    Integer tmp = iA;
    iA = iB;
    iB = tmp;
  }
}

ছাপে:

আগে: a = 2, b = 3 এর
পরে: a = 2, b = 3

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


32

জাভা শুধুমাত্র মান দ্বারা পাস করেছে। এটি যাচাই করার জন্য একটি খুব সাধারণ উদাহরণ।

public void test() {
    MyClass obj = null;
    init(obj);
    //After calling init method, obj still points to null
    //this is because obj is passed as value and not as reference.
}
private void init(MyClass objVar) {
    objVar = new MyClass();
}

4
জাভা মান দ্বারা পাস হয় এটি দেখতে এটি সবচেয়ে পরিষ্কার এবং সহজ উপায়। obj( null) এর মানটি প্রেরণ করা হয়েছিল init, কোনও রেফারেন্স নয় obj
ডেভিড শোয়ার্টজ

31

আমি এটিকে সবসময় "অনুলিপি দ্বারা পাস" মনে করি। এটি আদিম বা রেফারেন্স হওয়া মানটির একটি অনুলিপি। এটি যদি আদিম হয় তবে এটি হ'ল বিটগুলির একটি অনুলিপি এবং যদি এটি কোনও অবজেক্ট হয় তবে এটি রেফারেন্সের একটি অনুলিপি।

public class PassByCopy{
    public static void changeName(Dog d){
        d.name = "Fido";
    }
    public static void main(String[] args){
        Dog d = new Dog("Maxx");
        System.out.println("name= "+ d.name);
        changeName(d);
        System.out.println("name= "+ d.name);
    }
}
class Dog{
    public String name;
    public Dog(String s){
        this.name = s;
    }
}

জাভা PassByCopy এর আউটপুট:

নাম = ম্যাক্সেক্স
নাম = ফিডো

আদিম মোড়কের ক্লাস এবং স্ট্রিংগুলি অপরিবর্তনীয় তাই এই ধরণের ব্যবহারের কোনও উদাহরণ অন্য ধরণের / অবজেক্টের মতো কাজ করবে না।


5
"কপি পাস" কি পাস-বাই-মান মানে
টিজে ক্রাউডার

@TJCrowder। "অনুলিপি দ্বারা পাস" জাভা উদ্দেশ্যে একই ধারণাটি প্রকাশ করার আরও উপযুক্ত উপায় হতে পারে: কারণ শব্দার্থগতভাবে এটি জাভাতে আপনি যা চান তা যা রেফারেন্স দ্বারা পাস করার অনুরূপ ধারণায় জুতো রাখা খুব কঠিন করে তোলে।
মাইক রডেন্ট

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

28

অন্য কয়েকটি ভাষার মতো নয়, জাভা আপনাকে পাস-বাই-মান এবং পাস-বাই-রেফারেন্সের মধ্যে চয়ন করতে দেয় না — সমস্ত আর্গুমেন্টটি মান দ্বারা পাস হয়। একটি পদ্ধতি কল একটি পদ্ধতিতে দুটি ধরণের মানগুলি পাস করতে পারে pr আদিম মানের অনুলিপি (যেমন, আন্ত এবং দ্বিগুণের মান) এবং অবজেক্টের রেফারেন্সের অনুলিপি।

যখন কোনও পদ্ধতি একটি আদিম-ধরণের পরামিতিটি সংশোধন করে, কলিং পদ্ধতিতে প্যারামিটারে পরিবর্তনগুলি মূল আর্গুমেন্ট মানের উপর কোনও প্রভাব ফেলবে না।

যখন বস্তুর কথা আসে তখন বস্তুগুলি সেগুলি পদ্ধতিতে দেওয়া যায় না। সুতরাং আমরা বস্তুর রেফারেন্স (ঠিকানা) পাস করি pass আমরা এই রেফারেন্সটি ব্যবহার করে আসল অবজেক্টটি চালিত করতে পারি।

জাভা কীভাবে বস্তু তৈরি করে এবং সঞ্চয় করে: আমরা যখন কোনও বস্তু তৈরি করি তখন আমরা বস্তুর ঠিকানা একটি রেফারেন্স ভেরিয়েবলে সঞ্চয় করি। আসুন নীচের বিবৃতিটি বিশ্লেষণ করা যাক।

Account account1 = new Account();

"অ্যাকাউন্ট অ্যাকাউন্ট 1" হল রেফারেন্স ভেরিয়েবলের ধরণ এবং নাম, "=" হ'ল অ্যাসাইনমেন্ট অপারেটর, "নতুন" সিস্টেম থেকে প্রয়োজনীয় পরিমাণ জায়গার জন্য জিজ্ঞাসা করে। নতুন কীওয়ার্ডের ডানদিকে নির্মাণকারী যা বস্তুটি তৈরি করে তাকে নতুন কীওয়ার্ডের দ্বারা অন্তর্নিহিত বলা হয়। নির্ধারিত অবজেক্টের ঠিকানা (ডান মানের ফলাফল, যা "শ্রেণীর উদাহরণ সৃষ্টি অভিব্যক্তি" বলে একটি অভিব্যক্তি) বাম মানকে (যা একটি নাম এবং একটি নির্দিষ্ট ধরণের নির্দিষ্ট করে একটি রেফারেন্স ভেরিয়েবল) বরাদ্দ করা হয়েছে বরাদ্দকারী অপারেটরটি ব্যবহার করে।

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

অ্যারেগুলির পরিবর্তে অ্যারেগুলির পরিবর্তে অ্যারেগুলিতে রেফারেন্সগুলি প্রেরণ করা পারফরম্যান্সের কারণে বোঝায়। জাভাতে সমস্ত কিছু মান দ্বারা পাস করা হয়, যদি অ্যারে বস্তুগুলি পাস করা হয় তবে প্রতিটি উপাদানটির একটি অনুলিপি পাস হবে। বড় অ্যারেগুলির জন্য, এটি সময় নষ্ট করে এবং উপাদানগুলির অনুলিপিগুলির জন্য যথেষ্ট সঞ্চয়স্থান গ্রহণ করে।

নীচের চিত্রটিতে আপনি দেখতে পাচ্ছেন যে আমাদের দুটি রেফারেন্স ভেরিয়েবল রয়েছে (এগুলিকে সি / সি ++ এ পয়েন্টার বলা হয় এবং আমি মনে করি যে শব্দটি এই বৈশিষ্ট্যটি বোঝা সহজ করে তোলে)) আদিম এবং রেফারেন্স ভেরিয়েবলগুলি স্ট্যাক মেমোরিতে রাখা হয় (নীচের চিত্রগুলির বাম দিকে)। অ্যারে 1 এবং অ্যারে 2 রেফারেন্স ভেরিয়েবলগুলি "পয়েন্ট" (যেমন সি / সি ++ প্রোগ্রামাররা এটি কল করে) বা যথাক্রমে a এবং b অ্যারে রেফারেন্স, যা বস্তু (এই রেফারেন্স ভেরিয়েবলগুলির ধারণাগুলি হ'ল বস্তুর ঠিকানা) নীচে মেমোরিতে (নীচের চিত্রগুলিতে ডান দিকের) ।

মান উদাহরণ 1 দিয়ে পাস

যদি আমরা বিপরীতআরে পদ্ধতিতে আর্গুমেন্ট হিসাবে অ্যারে 1 রেফারেন্স ভেরিয়েবলের মানটি পাস করি তবে পদ্ধতিতে একটি রেফারেন্স ভেরিয়েবল তৈরি হয় এবং সেই রেফারেন্স ভেরিয়েবল একই অ্যারে (ক) এর দিকে নির্দেশ করা শুরু করে।

public class Test
{
    public static void reverseArray(int[] array1)
    {
        // ...
    }

    public static void main(String[] args)
    {
        int[] array1 = { 1, 10, -7 };
        int[] array2 = { 5, -190, 0 };

        reverseArray(array1);
    }
}

মান উদাহরণ দিয়ে পাস 2

সুতরাং, আমরা যদি বলি

array1[0] = 5;

বিপরীতক্রমে পদ্ধতিতে এটি অ্যারেতে পরিবর্তন আনবে।

রিভার্সআরাই পদ্ধতিতে আমাদের আরও একটি রেফারেন্স ভেরিয়েবল রয়েছে (অ্যারে 2) যা অ্যারে সি তে নির্দেশ করে। আমরা যদি বলি

array1 = array2;

বিপরীত অ্যারে পদ্ধতিতে, তারপরে পদ্ধতিতে উল্টো অ্যারে 1 এর রেফারেন্স ভেরিয়েবল অ্যারেতে পয়েন্ট করা বন্ধ করবে এবং অ্যারে সি-তে নির্দেশ করা শুরু করবে (দ্বিতীয় চিত্রের মধ্যে বিন্দুযুক্ত রেখা)।

যদি আমরা পদ্ধতির বিপরীতে অ্যারে 2 এর রেফারেন্স মান হিসাবে রেফারেন্স ভেরিয়েবল অ্যারে 2 এর মানটি ফিরিয়ে আনি এবং এই মানটিকে মূল পদ্ধতিতে রেফারেন্স ভ্যারিয়েবল অ্যারে 1 তে নির্ধারিত করি তবে মূল অ্যারে 1 অ্যারে সি তে নির্দেশ করা শুরু করবে।

সুতরাং আসুন আমরা এখনই একবারে করা সমস্ত জিনিস লিখি।

public class Test
{
    public static int[] reverseArray(int[] array1)
    {
        int[] array2 = { -7, 0, -1 };

        array1[0] = 5; // array a becomes 5, 10, -7

        array1 = array2; /* array1 of reverseArray starts
          pointing to c instead of a (not shown in image below) */
        return array2;
    }

    public static void main(String[] args)
    {
        int[] array1 = { 1, 10, -7 };
        int[] array2 = { 5, -190, 0 };

        array1 = reverseArray(array1); /* array1 of 
         main starts pointing to c instead of a */
    }
}

এখানে চিত্র বর্ণনা লিখুন

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

আপনি মূল অ্যারে 1 এ অ্যারে 2 এর মানও নির্ধারণ করতে পারেন। অ্যারে 1 বি দিকে নির্দেশ করা শুরু করবে।


27

আমি এখানে যে কোনও প্রোগ্রামিং ভাষার জন্য এই ধরণের প্রশ্নের জন্য নিবেদিত একটি থ্রেড তৈরি করেছি ।

জাভাও উল্লেখ করা হয়েছে । এখানে সংক্ষিপ্তসারটি দেওয়া হল:

  • জাভা এটি মান দ্বারা পরামিতি পাস
  • "মান দ্বারা" কোনও পদ্ধতিতে একটি প্যারামিটার পাস করার জাভা একমাত্র উপায়
  • পরামিতি হিসাবে প্রদত্ত বস্তু থেকে পদ্ধতিগুলি ব্যবহার করে বস্তুটিকে পরিবর্তিত করবে কারণ মূল বস্তুগুলিকে রেফারেন্স নির্দেশ করে। (যদি সেই পদ্ধতিটি নিজেই কিছু মান পরিবর্তন করে)

27

একটি দীর্ঘ গল্প সংক্ষিপ্ত করতে, জাভা অবজেক্টগুলির কিছু খুব অদ্ভুত বৈশিষ্ট্য রয়েছে।

সাধারণভাবে, জাভা আদিম ধরনের (হয়েছে int, bool, char, double, ইত্যাদি) মান সরাসরি গৃহীত হয় যে। তারপরে জাভাতে অবজেক্টস রয়েছে (যা থেকে উদ্ভূত সমস্ত কিছু java.lang.Object)। অবজেক্টস আসলে সবসময় একটি রেফারেন্সের মাধ্যমে পরিচালিত হয় (একটি রেফারেন্স পয়েন্টার যা আপনি স্পর্শ করতে পারবেন না)। এর অর্থ হল যে কার্যত, বস্তুগুলি রেফারেন্স দ্বারা প্রেরণ করা হয়, কারণ রেফারেন্সগুলি সাধারণত আকর্ষণীয় নয়। তবে এর অর্থ এই নয় যে রেফারেন্সটি মান দ্বারা প্রেরণ হওয়ায় আপনি কোন অবজেক্টটি নির্দেশ করতে পারেন তা পরিবর্তন করতে পারবেন না।

এই শব্দটি কি অদ্ভুত এবং বিভ্রান্তিমূলক মনে হচ্ছে? আসুন বিবেচনা করা যাক কী সি প্রয়োগকারীগুলি রেফারেন্সের মাধ্যমে পাস করে এবং মান দিয়ে যায়। সি-তে, ডিফল্ট কনভেনশনটি মান দ্বারা পাস হয়। void foo(int x)মান দ্বারা একটি int পাস। void foo(int *x)একটি ফাংশন যে একটি না চান int a, কিন্তু কোন int একটি পয়েন্টার: foo(&a)। একটি &অপারেটরের সাথে এটি একটি চলক ঠিকানা পাস করার জন্য ব্যবহার করবে ।

এটি সি ++ এ নিন এবং আমাদের উল্লেখ রয়েছে। রেফারেন্সগুলি মূলত (এই প্রসঙ্গে) সিনট্যাকটিক চিনি যা সমীকরণের পয়েন্টার অংশটি আড়াল করে: void foo(int &x)তাকে বলা হয় foo(a), যেখানে সংকলক নিজেই জানেন যে এটি একটি রেফারেন্স এবং অ-রেফারেন্সের ঠিকানাটি aপাস করা উচিত। জাভাতে, অবজেক্টগুলিকে উল্লেখ করা সমস্ত ভেরিয়েবলগুলি আসলে রেফারেন্স টাইপের হয়, কার্যত জরিমানা দানাদার নিয়ন্ত্রণ (এবং জটিলতা) ব্যতীত বেশিরভাগ উদ্দেশ্য এবং উদ্দেশ্যে রেফারেন্স দ্বারা কল করতে বাধ্য করা হয়, উদাহরণস্বরূপ, সি ++।


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