জাভাতে আদিমদের জন্য রেফারেন্স দিয়ে পাসের সমতুল্য কীভাবে করবেন


116

এই জাভা কোড:

public class XYZ {   
    public static void main(){  
        int toyNumber = 5;   
        XYZ temp = new XYZ();  
        temp.play(toyNumber);  
        System.out.println("Toy number in main " + toyNumber);  
    }

    void play(int toyNumber){  
        System.out.println("Toy number in play " + toyNumber);   
        toyNumber++;  
        System.out.println("Toy number in play after increement " + toyNumber);   
    }   
}  

এটি আউটপুট হবে:

 
খেলায় খেলনা সংখ্যা 5  
মতবিরোধের পরে খেলতে খেলনা সংখ্যা 6  
প্রধান 5 এ খেলনা সংখ্যা  

সি ++ এ আমি toyNumberছায়া এড়ানো বা নীচের মত একই ভেরিয়েবলের একটি অনুলিপি তৈরি করতে রেফারেন্স দ্বারা পাস হিসাবে চলকটি পাস করতে পারি :

void main(){  
    int toyNumber = 5;  
    play(toyNumber);  
    cout << "Toy number in main " << toyNumber << endl;  
}

void play(int &toyNumber){  
    cout << "Toy number in play " << toyNumber << endl;   
    toyNumber++;  
    cout << "Toy number in play after increement " << toyNumber << endl;   
} 

এবং সি ++ আউটপুটটি এটি হবে:

খেলায় খেলনা সংখ্যা 5  
মতবিরোধের পরে খেলতে খেলনা সংখ্যা 6  
প্রধান 6 এ খেলনা সংখ্যা  

আমার প্রশ্নটি হল - জাভাতে সমমানের কোডটি সি ++ কোডের মতো একই আউটপুটটি পেতে, রেফারেন্স দিয়ে পাসের পরিবর্তে জাভা দিয়ে মান দ্বারা পাস করা হয় ?


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

1
@ ড্যারেনডাব্লু আমি সম্পূর্ণরূপে একমত - পুনরায় খুলতে ভোট দিয়েছি। ওহ, এবং আপনার এটির জন্য যথেষ্ট খ্যাতি রয়েছে :-)
ডানকান জোন্স

আদিমদের চারপাশের আলোচনাটি বরং বিভ্রান্তিকর, কারণ প্রশ্নটি রেফারেন্স মানগুলিতে সমানভাবে প্রযোজ্য।
shmosel

"সি ++ এ আমি ছায়া এড়ানোর জন্য রেফারেন্স হিসাবে টয়নিम्बर ভেরিয়েবলটিকে পাস হিসাবে পাস করতে পারি" - এটি শেডিং নয় কারণ পদ্ধতিতে toyNumberঘোষিত ভেরিয়েবল mainপদ্ধতিতে সুযোগ নেই play। স্কোপগুলির বাসা বাঁধলে কেবল সি ++ এবং জাভাতে শেডিং হয়। En.wikedia.org/wiki/Variable_SdOWing দেখুন ।
স্টিফেন সি

উত্তর:


171

আপনার বেশ কয়েকটি পছন্দ আছে। যেটি সর্বাধিক বোধ করে তা হ'ল আপনি যা করার চেষ্টা করছেন তার উপর নির্ভর করে।

পছন্দ 1: টয়নিম্বারে একটি ক্লাসে সর্বজনীন সদস্য পরিবর্তনশীল করুন

class MyToy {
  public int toyNumber;
}

তারপরে আপনার পদ্ধতিতে একটি MyToy এর জন্য একটি রেফারেন্স পাস করুন।

void play(MyToy toy){  
    System.out.println("Toy number in play " + toy.toyNumber);   
    toy.toyNumber++;  
    System.out.println("Toy number in play after increement " + toy.toyNumber);   
}

পছন্দ 2: রেফারেন্স দ্বারা পাসের পরিবর্তে মানটি ফিরিয়ে দিন

int play(int toyNumber){  
    System.out.println("Toy number in play " + toyNumber);   
    toyNumber++;  
    System.out.println("Toy number in play after increement " + toyNumber);   
    return toyNumber
}

এই পছন্দটির জন্য মূলত কলসিতে একটি ছোট পরিবর্তন প্রয়োজন হবে যাতে এটি পড়ে toyNumber = temp.play(toyNumber);,।

পছন্দ 3: এটিকে একটি শ্রেণি বা স্থির পরিবর্তনশীল করুন make

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

পছন্দ 4: প্রকারের একটি একক উপাদান অ্যারে তৈরি করুন এবং এটি পাস করুন

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

void play(int [] toyNumber){  
    System.out.println("Toy number in play " + toyNumber[0]);   
    toyNumber[0]++;  
    System.out.println("Toy number in play after increement " + toyNumber[0]);   
}

2
স্পষ্ট ব্যাখ্যা এবং পছন্দসই প্রভাবটির জন্য কোড কীভাবে একাধিক পছন্দ সরবরাহের জন্য বিশেষত ভাল। আমি এখনই কাজ করছি এমন কোনও কিছুর জন্য সরাসরি সহায়ক! বাদাম যে এই প্রশ্নটি বন্ধ ছিল।
ড্যারেনডাব্লু

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

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

পছন্দ 2 এর আরও ব্যাখ্যা প্রয়োজন: মূলত কল সাইটটি toyNumber = temp.play(toyNumber);এটি পছন্দসইভাবে কাজ করার জন্য পরিবর্তন করতে হবে।
টুলমেকারস্টেভ

1
এটি অত্যন্ত কুৎসিত এবং এটির জন্য একটি হ্যাকিশ অনুভূতি রয়েছে ... কেন এত মৌলিক কিছু ভাষার একটি অংশ নয়?
shinzou

30

জাভা রেফারেন্সের মাধ্যমে কল হয় না এটি কেবল মূল্য দিয়ে কল হয়

তবে অবজেক্ট টাইপের সমস্ত ভেরিয়েবল আসলে পয়েন্টার।

সুতরাং আপনি যদি কোনও মিউটেবল অবজেক্ট ব্যবহার করেন আপনি নিজের পছন্দমতো আচরণ দেখতে পাবেন

public class XYZ {

    public static void main(String[] arg) {
        StringBuilder toyNumber = new StringBuilder("5");
        play(toyNumber);
        System.out.println("Toy number in main " + toyNumber);
    }

    private static void play(StringBuilder toyNumber) {
        System.out.println("Toy number in play " + toyNumber);
        toyNumber.append(" + 1");
        System.out.println("Toy number in play after increement " + toyNumber);
    }
}

এই কোডের আউটপুট:

run:
Toy number in play 5
Toy number in play after increement 5 + 1
Toy number in main 5 + 1
BUILD SUCCESSFUL (total time: 0 seconds)

আপনি স্ট্যান্ডার্ড লাইব্রেরিতেও এই আচরণটি দেখতে পারেন। উদাহরণস্বরূপ কালেকশনস.সোর্ট (); Collections.shuffle (); এই পদ্ধতিগুলি কোনও নতুন তালিকা ফেরত দেয় না তবে এটির যুক্তিযুক্ত বিষয়টিকে পরিবর্তন করে।

    List<Integer> mutableList = new ArrayList<Integer>();

    mutableList.add(1);
    mutableList.add(2);
    mutableList.add(3);
    mutableList.add(4);
    mutableList.add(5);

    System.out.println(mutableList);

    Collections.shuffle(mutableList);

    System.out.println(mutableList);

    Collections.sort(mutableList);

    System.out.println(mutableList);

এই কোডের আউটপুট:

run:
[1, 2, 3, 4, 5]
[3, 4, 1, 5, 2]
[1, 2, 3, 4, 5]
BUILD SUCCESSFUL (total time: 0 seconds)

2
এটি প্রশ্নের উত্তর নয়। এটি প্রশ্নের উত্তর দিতে পারত, যদি এটি একটি একক উপাদান যুক্ত একটি পূর্ণসংখ্যা অ্যারে তৈরি করার পরামর্শ দেয় এবং তারপরে পদ্ধতির মধ্যে সেই উপাদানটি সংশোধন করে play; যেমন mutableList[0] = mutableList[0] + 1;। আর্নেস্ট ফ্রেডম্যান-হিলের পরামর্শ মতো।
টুলমেকারস্টেভ

অ-আদিম সঙ্গে। অবজেক্টের মান কোনও রেফারেন্স নয়। হতে পারে আপনি বলতে চেয়েছিলেন: "প্যারামিটার মান" হল "একটি রেফারেন্স"। উল্লেখগুলি মান দ্বারা পাস করা হয়।
vlakov

আমি অনুরূপ কিছু করার চেষ্টা করছি তবে আপনার কোডে, পদ্ধতিতে private static void play(StringBuilder toyNumber)- উদাহরণস্বরূপ পাবলিক স্ট্যাটিক ইনট যা কোনও পূর্ণসংখ্যা ফেরত দিচ্ছে আপনি কীভাবে এটিকে কল করবেন? কারণ আমার একটি পদ্ধতি রয়েছে যা একটি নম্বর দেয় তবে আমি যদি এটি কোথাও কল না করি তবে এটি ব্যবহার হয় না।
খোলামেলা 17

18

একটি করা

class PassMeByRef { public int theValue; }

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


3
আমার দ্বারা বঞ্চিত অনেক মাত্রা উপর ভুল। জাভা সর্বদা মান দ্বারা পাস হয়। কোন আশা নাই.
duffymo

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

7
@ ডিফাইমো: হাহ? আপনি ভুল হয়ে গেছেন, না হলে প্রশ্নটি ভুল বুঝবেন। এই IS কি ওপি অনুরোধ করছেন জাভা চিরন্তন পদ্ধতি এক।
টুলমেকারস্টেভ

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

2
@ ডুফাইমো যা আমি বলেছিলাম ঠিক সেটাই: মান অনুসারে রেফারেশন দিন। আপনি কীভাবে ভাবেন যে রেফ বাই পাসটি এমন ভাষায় সম্পন্ন হয় যা এটি ধীর করে দেয়?
ইনগ্রে

11

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

এমন পরিস্থিতিতে যেখানে আপনাকে সত্যিকার অর্থে রেফারেন্স দিয়ে একটি আদিম পাস করতে হবে, লোকেরা কখনও কখনও কী করবে তা প্যারামিটারটিকে আদিম ধরণের অ্যারে হিসাবে ঘোষণা করে এবং তারপরে একটি একক-উপাদান অ্যারেটিকে আর্গুমেন্ট হিসাবে পাস করে। সুতরাং আপনি একটি রেফারেন্স ইনট [1] পাস করুন এবং পদ্ধতিতে আপনি অ্যারের সামগ্রীগুলি পরিবর্তন করতে পারেন।


1
না - সমস্ত মোড়কের ক্লাস অপরিবর্তনীয় - তারা একটি নির্দিষ্ট মান উপস্থাপন করে যা বস্তুটি তৈরি হওয়ার পরে পরিবর্তন করা যায় না।
আর্নেস্ট ফ্রেডম্যান-হিল

1
"আপনি জাভাতে রেফারেন্স দিয়ে আদিমকে পাস করতে পারবেন না": ওপি জাভির সাথে সি ++ (আপনি যেখানে পারেন) এর বিপরীতে আছেন বলে এটি বুঝতে পারে।
রায়েডওয়াল্ড

এটি লক্ষ করা উচিত যে আর্নেস্টের দ্বারা বলা "সমস্ত মোড়কের ক্লাসগুলি অপরিবর্তনীয়" জেডিকে বিল্ড-ইন ইন্টিজার, ডাবল, লং ইত্যাদির ক্ষেত্রে প্রযোজ্য In
ব্যবহারকারী3207158

10

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

import java.util.concurrent.atomic.AtomicInteger;


public class PrimitivePassByReferenceSample {

    /**
     * @param args
     */
    public static void main(String[] args) {

        AtomicInteger myNumber = new AtomicInteger(0);
        System.out.println("MyNumber before method Call:" + myNumber.get());
        PrimitivePassByReferenceSample temp = new PrimitivePassByReferenceSample() ;
        temp.changeMyNumber(myNumber);
        System.out.println("MyNumber After method Call:" + myNumber.get());


    }

     void changeMyNumber(AtomicInteger myNumber) {
        myNumber.getAndSet(100);

    }

}

আউটপুট:

MyNumber before method Call:0

MyNumber After method Call:100

আমি এই সমাধানটি ব্যবহার করি এবং পছন্দ করি কারণ এটি দুর্দান্ত যৌগিক ক্রিয়াকলাপ সরবরাহ করে এবং সমবর্তী প্রোগ্রামগুলিতে ইন্টিগ্রেটেড করা সহজ যা ভবিষ্যতে ইতিমধ্যে বা ভবিষ্যতে এই পারমাণবিক শ্রেণিগুলি ব্যবহার করতে চাইতে পারে।
রেন্ডারস 300

2
public static void main(String[] args) {
    int[] toyNumber = new int[] {5};
    NewClass temp = new NewClass();
    temp.play(toyNumber);
    System.out.println("Toy number in main " + toyNumber[0]);
}

void play(int[] toyNumber){
    System.out.println("Toy number in play " + toyNumber[0]);
    toyNumber[0]++;
    System.out.println("Toy number in play after increement " + toyNumber[0]);
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.