যখন একটি পরামিতি আক্ষরিক নাল মান হয় তখন একটি ওভারলোডেড পদ্ধতি কীভাবে বেছে নেওয়া হয়?


98

আমি এই প্রশ্নটি একটি কুইজে এসেছি,

public class MoneyCalc {

   public void method(Object o) {
      System.out.println("Object Verion");
   }

   public void method(String s) {
      System.out.println("String Version");
   }

   public static void main(String args[]) {
      MoneyCalc question = new MoneyCalc();
      question.method(null);
   }
}

এই প্রোগ্রামটির আউটপুট "স্ট্রিং সংস্করণ"। তবে কেন আমি বোঝা গেলাম না যে ওভারলোডেড পদ্ধতিতে শূন্যস্থানটি কেন স্ট্রিং সংস্করণটি বেছে নিয়েছিল। নাল কি কোনও স্ট্রিং ভেরিয়েবল কিছুই নির্দেশ করছে?

তবে কোডটি যখন এতে পরিবর্তন করা হয়,

public class MoneyCalc {

   public void method(StringBuffer sb) {
      System.out.println("StringBuffer Verion");
   }

   public void method(String s) {
      System.out.println("String Version");
   }

   public static void main(String args[]) {
      MoneyCalc question = new MoneyCalc();
      question.method(null);
   }
}

এটি "সংক্ষেপে ত্রুটি দেয়" পদ্ধতিটি (স্ট্রিংবফার) মানি ক্যালক টাইপের জন্য অস্পষ্ট "


আপনি একটি নাল মানকে একটি স্ট্রিং বরাদ্দ করতে পারেন যাতে এটি বৈধ হয় এবং জাভা এবং বেশিরভাগ প্রোগ্রামিং ভাষার জন্য অর্ডারটি নিকটতম ধরণের এবং তারপরে আপত্তি জানাতে উপযুক্ত object
জোনএইচ


6
দৃশ্যত এটি কেবল শিরোনামটি পড়ে এমন লোকদের দ্বারা এটি সদৃশ হিসাবে বন্ধ ছিল was এখানে আসল প্রশ্নটি হল "কেন নাল" নয়, কেন একটি নির্দিষ্ট ওভারলোড বেছে নেওয়া হয়েছিল about
আন্তজয়

উত্তর:


102

নাল কি কোনও স্ট্রিং ভেরিয়েবল কিছুই নির্দেশ করছে?

একটি নাল রেফারেন্স যে কোনও শ্রেণির ধরণের এক্সপ্রেশনতে রূপান্তরিত হতে পারে। সুতরাং ক্ষেত্রে String, এটি ঠিক আছে:

String x = null;

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

অনানুষ্ঠানিক স্বজ্ঞাততা হ'ল প্রথম পদ্ধতির দ্বারা পরিচালিত কোনও অনুরোধ একটি সংকলন-সময় ধরণের ত্রুটি ছাড়াই অন্যটিতে প্রেরণ করা যেতে পারে তবে একটি পদ্ধতি অন্যর চেয়ে বেশি নির্দিষ্ট।

আপনার দ্বিতীয় ক্ষেত্রে, উভয় পদ্ধতি এখনও প্রযোজ্য, তবে উভয়ই নয় Stringবা StringBufferঅন্যটির চেয়েও সুনির্দিষ্ট নয়, সুতরাং কোনও পদ্ধতিই অন্যটির চেয়ে বেশি নির্দিষ্ট নয়, তাই সংকলক ত্রুটি।


4
এবং স্ট্রিং ওভারলোড কীভাবে অবজেক্ট ওভারলোডের চেয়ে বেশি নির্দিষ্ট?
ব্যবহারকারী 1610015

12
কারণ একটি Objectযে কোনও ধরণের নিতে পারে এবং এটি একটিতে গুটিয়ে রাখতে পারে Object, যখন একটি Stringকেবল একটি নিতে পারে String। এই ক্ষেত্রে, Stringপ্রকারের তুলনায় কোনও ধরণের আরও সুনির্দিষ্ট Object
জোনএইচ

10
@ জাকসিড যদি আপনাকে জিজ্ঞাসা করা হয় যে আরও বেশি স্ট্রিংড "স্ট্রিং" বা "অবজেক্ট" কী, আপনি কী বলবেন? স্পষ্টতই "স্ট্রিং", তাই না? যদি আপনাকে জিজ্ঞাসা করা হয়েছিল: "স্ট্রিং" বা "স্ট্রিংবফার" আরও বিশেষায়িত কী? কোনও উত্তর নেই, তারা উভয়ই অরথোগোনাল বিশেষীকরণ, আপনি কীভাবে তাদের মধ্যে বেছে নিতে পারেন? তারপরে আপনি অবশ্যই যা চান তার বিষয়ে আপনাকে অবশ্যই স্পষ্ট করে বলতে হবে (অর্থাত আপনার নাল রেফারেন্স দিয়ে question.method((String)null))
এডউইন ডালোরজো

4
@ জোনস্কিট: এটি উপলব্ধি করে। সুতরাং মূলত এটি সুনির্দিষ্ট নির্দিষ্ট নিয়ম অনুসারে একটি পদ্ধতি অনুসন্ধান করে এবং যদি এটি নির্দিষ্ট করে কোনটি নির্দিষ্ট করে তা সক্ষম না করে তবে এটি একটি সংকলন-সময় ত্রুটি নিক্ষেপ করবে।
জাকসিড

4
@ জোনএইচ "নাল" রেফারেন্স টাইপ, যদি পদ্ধতিগুলির মধ্যে কোনও একটি প্যারামিটার হিসাবে আদিম টাইপ পায় (অর্থাত্ int) এটি নকল প্রকারের রেফারেন্সের জন্য অনুরোধ করার জন্য সঠিক পদ্ধতিটি বেছে নেওয়ার সময় সংকলক দ্বারা বিবেচিত হবে না। এটি "বিভ্রান্তিমূলক" হয় যদি আপনি জাভা.লং.ইন্টেগার বোঝাতে চেয়েছিলেন বা আপনি যদি আদিম টাইপ ইন্ট বোঝাতেন।
এডউইন ডালোরজো

9

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

পরে, জেএলএস ৪.১ বলেছে যে এখানে একটি নাল ধরণের উপস্থিত রয়েছে যার মধ্যে ভেরিয়েবলগুলি ঘোষণা করা অসম্ভব তবে আপনি এটি কেবল নাল আক্ষরিক মাধ্যমে ব্যবহার করতে পারেন। পরে এটি বলে:

নাল রেফারেন্স সর্বদা যেকোন রেফারেন্স প্রকারে প্রসারিত রেফারেন্স রূপান্তরের মধ্য দিয়ে যেতে পারে।

সংকলক কেন স্ট্রিংয়ে এটি প্রশস্ত করতে পছন্দ করে তা জনের উত্তরে ব্যাখ্যা করা যেতে পারে ।


আমি পুরোপুরি নিশ্চিত যে টাইপটি অকার্যকর।
xavierm02

4
@ xavierm02 জাভা ভাষা নির্দিষ্টকরণে এর কোনও উল্লেখ নেই। আপনি কি আপনার উল্লেখটি উদ্ধৃত করতে পারেন যাতে আমরা সবাই আপনার দাবিটি যাচাই করতে পারি?
এডউইন ডালোরজো

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

এটি এক ধরণের চেয়ে শ্রেণির বেশি।
xavierm02

4
@ xavierm02 অবশ্যই আপনি পারেন। আপনি যে কোনও প্রকারের সাথে জাভাতে একটি পদ্ধতি ওভারলোড করতে পারেন। তবুও, এই প্রশ্নের বা আমার উত্তরটির সাথে কোনও সম্পর্ক নেই।
এডউইন ডালোরজো

2

আপনি stringকোনও nullমানকে একটি বরাদ্দ করতে পারেন যাতে এটি বৈধ এবং জাভা এবং বেশিরভাগ প্রোগ্রামিং ভাষার জন্য অর্ডারটি নিকটতম ধরণের এবং তারপরে আপত্তি জানাতে উপযুক্ত।


2

শিরোনামে প্রশ্নের উত্তর দেওয়ার জন্য: nullএকটিও Stringনয় এবং একটিও নয় Object, তবে উভয়ের মধ্যে একটি রেফারেন্সও দেওয়া যেতে পারে null

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

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

আমাকে দেখতে হবে যে আমি উদাহরণটি খনন করতে পারি কিনা যেখানে এই (আপাতদৃষ্টিতে) ঠিক একই দৃশ্যে একটি সংকলক ত্রুটি পেয়েছি যদিও ...]

সম্পাদনা: আমি দেখছি। আমি যে সংস্করণটি তৈরি করেছি তাতে আমার দুটি ওভারলোডেড পদ্ধতি গ্রহণ করেছে একটি Stringএবং একটি Integer। এই দৃশ্যকল্প ইন, (হিসাবে কোন "সবচেয়ে নির্দিষ্ট" প্যারামিটার Objectএবং String,) তাই এটি আপনার কোডে অসদৃশ, তাদের মধ্যে নির্বাচন করতে পারবে না।

খুব দুর্দান্ত প্রশ্ন!


নাল দুটি নয় তবে এটি উভয়কেই বরাদ্দ করা যেতে পারে, এটিই তফাত এবং এটি সংকলন করবে কেন এটি হবে না - এটি একেবারে বৈধ কোড।
জোনএইচ

0

স্ট্রিং টাইপ যেমন অবজেক্ট টাইপের চেয়ে বেশি নির্দিষ্ট। ধরা যাক আপনি আরও একটি পদ্ধতি যুক্ত করেছেন যা একটি পূর্ণসংখ্যার ধরণ নেয়।

public void method(Integer i) {
      System.out.println("Integer Version");
   }

তারপরে আপনি একটি সংকলক ত্রুটি পেয়ে যাবেন যে কলটি অস্পষ্ট। একই হিসাবে আমরা এখন দুটি সমান নির্দিষ্ট পদ্ধতি।


0

জাভা সংকলক নাল নির্ধারণের জন্য সর্বাধিক উত্সযুক্ত শ্রেণীর প্রকার দেয়।

এটি বোঝার উদাহরণ এখানে:

class A{

    public void methodA(){
        System.out.println("Hello methodA");
    }
}

class B extends A{
    public void methodB(){
        System.out.println("Hello methodB");
    }
}

class C{
    public void methodC(){
        System.out.println("Hello methodC");
    }
}

public class MyTest {

     public static void fun(B Obj){
         System.out.println("B Class.");
     }
     public static void fun(A Obj){
         System.out.println("A Class.");
     }

    public static void main(String[] args) {
        fun(null);
    }
}

আউটপুট: বি ক্লাস।

অন্য দিকে:

public class MyTest {

     public static void fun(C Obj){
         System.out.println("B Class.");
     }
     public static void fun(A Obj){
         System.out.println("A Class.");
     }

    public static void main(String[] args) {
        fun(null);
    }
}

ফলাফল: পদ্ধতিটি মজাদার (সি) মাই টেস্ট টাইপের জন্য অস্পষ্ট

আশা করি এটি এই কেসটি আরও ভালভাবে বুঝতে সহায়তা করবে।


0

উত্স: https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.5
ধারণা: সর্বাধিক নির্দিষ্ট পদ্ধতি
ব্যাখ্যা: যদি একাধিক সদস্য পদ্ধতি উভয়ই অ্যাক্সেসযোগ্য এবং কোনও পদ্ধতিতে প্রার্থনার জন্য প্রযোজ্য, রান-টাইম পদ্ধতি প্রেরণের জন্য বর্ণনাকারী সরবরাহ করার জন্য একটি বেছে নেওয়া প্রয়োজন। জাভা প্রোগ্রামিং ল্যাঙ্গুয়েজটি সুনির্দিষ্ট পদ্ধতিটি বেছে নেওয়ার নিয়মটি ব্যবহার করে। নির্দিষ্ট প্রকারে নালটি ingালতে চেষ্টা করুন এবং যে পদ্ধতিটি আপনি চান তা স্বয়ংক্রিয়ভাবে কল করা হবে।


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

-1

আমিও বলব না। NULL একটি রাষ্ট্র নয় একটি মান। এই সম্পর্কিত আরও তথ্যের জন্য এই লিঙ্কটি দেখুন (নিবন্ধটি এসকিউএল এর ক্ষেত্রে প্রযোজ্য, তবে আমি মনে করি এটি আপনার প্রশ্নের সাথেও সহায়তা করে)।


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