নাল আর্গুমেন্টের জন্য পদ্ধতি ওভারলোডিং


133

আমি প্যারামিটার সহ তিনটি পদ্ধতি যুক্ত করেছি:

public static  void doSomething(Object obj) {
    System.out.println("Object called");
}

public static  void doSomething(char[] obj) {
    System.out.println("Array called");
}

public static  void doSomething(Integer obj) {
    System.out.println("Integer called");
}

যখন আমি কল করছি doSomething(null), তখন সংকলকটি অস্পষ্ট পদ্ধতি হিসাবে ত্রুটি নিক্ষেপ করছে । তাই ইস্যু কারণ Integerএবং char[]পদ্ধতি বা Integerএবং Objectপদ্ধতি?


3
শুধু পরিবর্তন Integerকরতে int
মুদাসসির

2
@ মুদাসসির: আর এর সমাধান কী হবে?
জোচিম সৌর

2
@ জোয়াচিম সৌর: যদি পূর্ণসংখ্যার থেকে ইনট-এ পরিবর্তিত হয় তবে জাভাতে নালাকে আদিম ধরণের উল্লেখ করা হয় না, তাই সংকলক ত্রুটি ছুঁড়ে না ফেলে।
ফানি

@ জোয়াচিম সৌর: এটি reference to doSomething is ambiguousত্রুটিটি ছুঁড়ে ফেলবে না ।
মুদাসসির

উত্তর:


211

জাভা সর্বদা উপলব্ধ যে কোনও পদ্ধতির সুনির্দিষ্ট প্রযোজ্য সংস্করণটি ব্যবহার করার চেষ্টা করবে ( জেএলএস §15.12.2 দেখুন )।

Object, char[]এবং Integerসমস্ত nullএকটি বৈধ মান হিসাবে নিতে পারে। অতএব সমস্ত 3 সংস্করণ প্রযোজ্য, তাই জাভা সবচেয়ে সুনির্দিষ্ট একটি সন্ধান করতে হবে।

থেকে Object অতি-ধরণের char[], তাই অ্যারে সংস্করণটি সংস্করণটির চেয়ে বেশি নির্দিষ্ট Object। সুতরাং শুধুমাত্র যদি এই দুটি পদ্ধতি বিদ্যমান থাকে তবে char[]সংস্করণটি চয়ন করা হবে।

যখন char[]এবং উভয়Integer সংস্করণ সংস্করণ উপলব্ধ থাকে, তখন উভয়ই তার চেয়ে বেশি নির্দিষ্ট হয় Objectতবে কোনওটি অন্যটির চেয়ে বেশি নির্দিষ্ট নয়, তাই জাভা কোনটি কল করতে পারে তা সিদ্ধান্ত নিতে পারে না। এই ক্ষেত্রে আপনাকে যথাযথ প্রকারের পক্ষে যুক্তিটি কাস্ট করে কোনটিকে কল করতে চান তা স্পষ্টভাবে উল্লেখ করতে হবে।

নোট করুন যে অনুশীলনে এই সমস্যাটি ঘটে যা কেউ ভাবেন তার চেয়ে কদাচিৎ ঘটে। এর কারণ হ'ল এটি তখনই ঘটে যখন আপনি স্পষ্টভাবে কোনও পদ্ধতিটিকে কল nullনা করে বরং একটি নির্দিষ্ট-নির্দিষ্ট ধরণের ভেরিয়েবলের সাথে (যেমন:Object ) এর ।

বিপরীতে, নিম্নলিখিত প্রার্থনা পুরোপুরি দ্ব্যর্থহীন হবে:

char[] x = null;
doSomething(x);

যদিও আপনি এখনও মানটি পাস করছেন null, জাভা ঠিক কোন পদ্ধতিটি কল করতে হবে তা জানেন, কারণ এটি ভেরিয়েবলের ধরণটিকে বিবেচনা করবে।


1
এটি জাভা for এর জন্য বলা আছে এটি কি পূর্ববর্তী জাভা সংস্করণগুলিতেও প্রযোজ্য? আমি বলতে চাইছি: আপনি যদি একধরনের শ্রেণিবিন্যাসের সাথে পরামিতিগুলির সাথে একাধিক পদ্ধতি স্বাক্ষর রাখেন, তবে আপনি আসল মান হিসাবে নাল দিয়ে সেভ সাইডে আছেন? এবং যদি আপনি এখানে উদাহরণের মতো একটি "শ্রেণিবিন্যাস" তৈরি করে থাকেন, তবে আপনি না?
খ্রিস্টান গোশ

2
আমি নিশ্চিত যে জাভা 1.1 সাল থেকে কমপক্ষে প্রতিটি কিছুর জন্য এই নিয়মগুলি সমান (স্পষ্টতই জেনেরিক সংযোজন ব্যতীত) pretty
জোছিম সউর

এর অর্থ কি এই যে কম্পাইলারটি doSomething (নাল) দিয়ে রানটাইম চলাকালীন doSomething (স্ট্রিং str) এবং doSomething (অবজেক্ট অবজেক্ট) এর মধ্যে কোনটি বেছে নিলে doSomething (স্ট্রিং str) ডাকা হবে।
সমীর

42

এই তিনটি পদ্ধতির প্রতিটি জুটি যখন nullআর্গুমেন্টের সাথে ডাকা হয় তখন তা নিজেই দ্ব্যর্থক হয় । কারণ প্রতিটি প্যারামিটারের টাইপ একটি রেফারেন্স টাইপ।

নাল দিয়ে আপনার একটি নির্দিষ্ট পদ্ধতিতে কল করার জন্য তিনটি উপায়।

doSomething( (Object) null);
doSomething( (Integer) null);
doSomething( (char[]) null);

যদি আপনি আসলে এই পদ্ধতিগুলিকে nullযুক্তি দিয়ে কল করার পরিকল্পনা করেন তবে আমি এই অস্পষ্টতাটি সরিয়ে দেওয়ার পরামর্শ দিতে পারি । এই জাতীয় নকশা ভবিষ্যতে ত্রুটিগুলিকে আমন্ত্রণ জানায়।


1
কেবল Integer- char[]জুটি অস্পষ্ট, কারণ অন্য দুটি ক্ষেত্রে জাভা সংকলক সুনির্দিষ্ট পছন্দটি বেছে নিতে পারে, যেমন @ জোয়াচিমসৌর বর্ণিত।
কাজাক্স

1
@ কেজ্যাকেক্স: ওপিএসের মূল প্রশ্নটি nullপ্যারামিটার হিসাবে এই পদ্ধতিগুলি কল করার বিষয়ে ছিল । এই পূর্বশর্তের অধীনে, তিনটি জুটিই অস্পষ্ট। সাধারণ ক্ষেত্রে, আমি সম্মত হই যে কেবল Integer - char[]জোড়া দ্বিধাবিভক্ত।
jmg

কি doSomething(null)জন্য public static void doSomething(String str) { System.out.println("String called"); } এই স্ট্রিং কল ফিরে আসবে।
সমীর

"Nullaable" বা "nullable" বা "nullaable not" এর মতো একটি এনোটেশন ব্যবহার করা এবং ঘোষণাগুলি সেট আপ করা সম্ভব যাতে আপনি কেবলমাত্র একটি পদ্ধতির সাথে নাল পেতে চান যাতে একটি স্পষ্ট "নাল" (এখনও অন্তর্নিহিত নাল টাইপ) যুক্তি সর্বদা নির্বিঘ্নে নির্বাচন করে একটি নির্দিষ্ট ওভারলোড ??
পিটার্ক

4

nullতিন ধরণের যে কোনও একটির জন্য একটি বৈধ মান; সুতরাং সংকলক কোন ফাংশনটি ব্যবহার করবে তা সিদ্ধান্ত নিতে পারে না। এর মতো doSomething((Object)null)বা doSomething((Integer)null)পরিবর্তে কিছু ব্যবহার করুন ।


আমি ইন্টিজার প্যারামিটারের সাহায্যে পদ্ধতিটি সরিয়েছি, এটি ফাংশনটি শুরু করছে এবং আউটপুটটিকে "অ্যারে কলড" হিসাবে ফিরিয়েছে , সুতরাং অ্যারে এবং অবজেক্টের মধ্যে চুক্তি কী ?
ফানি

2
জাভা অ্যারেগুলিও অবজেক্ট।
জেডএস

2

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


1

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

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


0

ডসোমিংথিং (চর [] আপত্তি) এবং ডোসোমথিং (পূর্ণসংখ্যার আপত্তি) এর কারণে একটি অস্পষ্টতা রয়েছে।

চর [] এবং পূর্ণসংখ্যা উভয়ই যেহেতু দ্ব্যর্থকেন্দ্রিক হয় তা নাল ঠেকানোর জন্য সমান উচ্চতর।


0
class Sample{
  public static void main (String[] args) {
       Sample s = new Sample();
       s.printVal(null);

    } 
    public static void printVal(Object i){
        System.out.println("obj called "+i);
    }

    public static void printVal(Integer i){
        System.out.println("Int called "+i);
    }
}

আউটপুটটিকে ইন্ট নাল বলা হয় এবং তাই অস্পষ্টতা চর [] এবং পূর্ণসংখ্যার সাথে

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