স্ট্রিং ক্লাস কীভাবে + অপারেটরকে ওভাররাইড করে?


129

জাভাতে আপনি স্ট্রিং যখন একটি শ্রেণি হয় কেন + অপারেটরের সাথে স্ট্রিং যুক্ত করতে পারবেন? কোডটিতে String.javaআমি এই অপারেটরের জন্য কোনও প্রয়োগ খুঁজে পাইনি। এই ধারণাটি কি বস্তুগত অবস্থানকে লঙ্ঘন করে?


21
প্লাস ( +) অপারেটর জাভা ভাষার বৈশিষ্ট্য।
অ্যাডটাপস্ট

18
এটি সবই সংকলকের যাদু। আপনি জাভাতে অপারেটর ওভারলোডিং করতে পারবেন না।
সিংহ

18
আমি মনে করি আশ্চর্যের বিষয় হ'ল স্ট্রিং ভাষার বাইরে একটি লাইব্রেরি হিসাবে প্রয়োগ করা হয় (java.lang.String এ), তবুও ভাষার অভ্যন্তরে এর নির্দিষ্ট সমর্থন রয়েছে । এটা ঠিক নয়।
13ren


@ 13ren আপনি ভুল স্ট্রিং জাভা.এলং ক্লাসের বাইরে যা ভাষার জন্য দাঁড়ায় - জাভা ল্যাঙ্গেজ !!! এই প্যাকেজের সমস্ত শ্রেণি বিশেষ। লক্ষ্য করুন যে এগুলি ব্যবহার করার জন্য আপনাকে java.lang আমদানি করতে হবে না।

উত্তর:


156

আসুন জাভাতে নিম্নলিখিত সহজ অভিব্যক্তি তাকান

int x=15;
String temp="x = "+x;

কম্পাইলার ধর্মান্তরিত "x = "+x;একটি মধ্যে StringBuilderঅভ্যন্তরীণভাবে এবং ব্যবহার .append(int)করার জন্য স্ট্রিং পূর্ণসংখ্যা "যোগ"।

5.1.11। স্ট্রিং রূপান্তর

যে কোনও প্রকার স্ট্রিং রূপান্তর দ্বারা স্ট্রিং টাইপ রূপান্তরিত হতে পারে।

আদিম প্রকার টিয়ের একটি মান x প্রথমে একটি রেফারেন্স মানটিতে রূপান্তরিত হয় যেন এটি কোনও উপযুক্ত শ্রেণীর উদাহরণ তৈরির এক্সপ্রেশনকে (§15.9) যুক্তি হিসাবে দিয়ে:

  • যদি টি বুলিয়ান হয়, তবে নতুন বুলিয়ান (এক্স) ব্যবহার করুন।
  • যদি টি চর হয়, তবে নতুন অক্ষর (এক্স) ব্যবহার করুন।
  • টি যদি বাইট, সংক্ষিপ্ত বা ইনট হয় তবে নতুন পূর্ণসংখ্যা (এক্স) ব্যবহার করুন।
  • টি যদি দীর্ঘ হয় তবে নতুন লং (এক্স) ব্যবহার করুন।
  • যদি টি ফ্লোট হয় তবে নতুন ফ্লোট (এক্স) ব্যবহার করুন।
  • যদি টি ডাবল হয় তবে নতুন ডাবল (এক্স) ব্যবহার করুন।

এই রেফারেন্স মানটি স্ট্রিং রূপান্তর দ্বারা স্ট্রিং টাইপ রূপান্তরিত হয়।

এখন কেবলমাত্র রেফারেন্স মানগুলি বিবেচনা করা দরকার:

  • যদি রেফারেন্সটি নাল হয় তবে এটি "নাল" স্ট্রিংয়ে রূপান্তরিত হয় (চারটি ASCII অক্ষর n, u, l, l)।
  • অন্যথায় রূপান্তরটি এমনভাবে সঞ্চালিত হয় যেন কোনও আর্গুমেন্ট ছাড়াই রেফারেন্সযুক্ত অবজেক্টের টো স্ট্রিং পদ্ধতির ডাকে; তবে যদি স্ট্রিং পদ্ধতিটি চাওয়ার ফলাফলটি নাল হয় তবে তার পরিবর্তে "নাল" স্ট্রিংটি ব্যবহৃত হয়।

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

স্ট্রিং রূপান্তর প্রসঙ্গে বিশদ জানতে §5.4 দেখুন।

15.18.1।

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

আদিম ধরণের জন্য, একটি বাস্তবায়ন একটি আদিম প্রকারটি সরাসরি স্ট্রিংয়ে রূপান্তর করে একটি মোড়কের বস্তুর তৈরি অপসারণ করতে পারে।

অপ্টিমাইজড সংস্করণটি প্রথমে প্রথমে পুরো মোড়ক স্ট্রিং রূপান্তরটি করবে না।

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

http://caprazzi.net/posts/java-bytecode-string-concatenation-and-stringbuilder/


এই জাভা কোড:

public static void main(String[] args) {
    String cip = "cip";
    String ciop = "ciop";
    String plus = cip + ciop;
    String build = new StringBuilder(cip).append(ciop).toString();
}

এটি উত্পন্ন করে - দেখুন দুটি কনটেনটেশন শৈলী কীভাবে একেবারে একই বাইকোডে নিয়ে যায়:

 L0
    LINENUMBER 23 L0
    LDC "cip"
    ASTORE 1
   L1
    LINENUMBER 24 L1
    LDC "ciop"
    ASTORE 2

   // cip + ciop

   L2
    LINENUMBER 25 L2

    NEW java/lang/StringBuilder
    DUP
    ALOAD 1
    INVOKESTATIC java/lang/String.valueOf(Ljava/lang/Object;)Ljava/lang/String;
    INVOKESPECIAL java/lang/StringBuilder.<init>(Ljava/lang/String;)V
    ALOAD 2
    INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;

    ASTORE 3

    // new StringBuilder(cip).append(ciop).toString()

   L3
    LINENUMBER 26 L3

    NEW java/lang/StringBuilder
    DUP
    ALOAD 1
    INVOKESPECIAL java/lang/StringBuilder.<init>(Ljava/lang/String;)V
    ALOAD 2
    INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;

    ASTORE 4
   L4
    LINENUMBER 27 L4
    RETURN

উপরের উদাহরণটি এবং প্রদত্ত উদাহরণে উত্স কোডের উপর ভিত্তি করে বাইট কোডটি কীভাবে উত্পন্ন হয় তা দেখে আপনি লক্ষ্য করতে পারবেন যে সংকলকটি নীচের বিবৃতিটি অভ্যন্তরীণভাবে রূপান্তর করেছে

cip+ciop; 

মধ্যে

new StringBuilder(cip).append(ciop).toString();

অন্য কথায়, +স্ট্রিং কনটেন্টেশন অপারেটর কার্যকরভাবে আরও ভার্জোজ StringBuilderআইডিয়ামের জন্য একটি শর্টহ্যান্ড ।


3
অনেক ধন্যবাদ, আমি jvm বাইট কোডের সাথে পরিচিত নই তবে স্ট্রিং প্লাস = সিপ + সিওপের জন্য উত্পন্ন কোড; এবং স্ট্রিং বিল্ড = নতুন স্ট্রিংবিল্ডার (সিপ)। অ্যাপেন্ড (সিওপ)। টু স্ট্রিং (); সমান এবং আমার প্রশ্ন হ'ল এই অপারেশনটি কি বস্তুগত দিকনির্দেশনা লঙ্ঘন করে?
পুয়া

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

2
হ্যাঁ, তবে আমি মনে করি এই অপারেটর স্ট্রিং ক্লাসের জন্য ওভারলোড করেছে
পুয়া

3
হ্যাঁ, স্ট্রিং টাইপের সংমিশ্রনের জন্য জাভাতে অপারেটর ওভারলোডিং ব্যবহৃত হয় তবে আপনি নিজের অপারেটরটি সংজ্ঞায়িত করতে পারবেন না (যেমন সি ++, সি # এবং কিছু অন্যান্য ভাষায়)।
সিংহ

5
@ পুয়া: আসলে "ইনট / ইনট" বনাম "ইনট / ফ্লোট" ইতিমধ্যে অপারেটর ওভারলোডিং, তাই সি- তেও এটি রয়েছে। তবে সি (এবং জাভা) যা ব্যবহার করে না তা হ'ল ব্যবহারকারী-সংজ্ঞায়িত অপারেটর ওভারলোডিং: অপারেটর যেভাবে বিভিন্ন পদ্ধতি ব্যবহার করতে পারে (সি এবং জাভা উভয় ক্ষেত্রে) কেবলমাত্র সেগুলিই ভাষা সংজ্ঞা (এবং পার্থক্যটি প্রয়োগ করা হয় কম্পাইলার)। সি ++ এর থেকে পৃথক যে এটি ব্যবহারকারীর দ্বারা সংজ্ঞায়িত অপারেটরকে ওভারলোডিং (যা প্রায়শই কেবল "অপারেটর ওভারলোডিং" হিসাবে পরিচিত)।
জোছিম সউর

27

এটি জাভা সংকলক বৈশিষ্ট্য যা +অপারেটরের ক্রিয়াকলাপ পরীক্ষা করে । এবং অপারেন্ডগুলির উপর ভিত্তি করে এটি বাইট কোড উত্পন্ন করে:

  • স্ট্রিংয়ের জন্য, এটি কনক্রিট স্ট্রিং থেকে কোড উত্পন্ন করে
  • সংখ্যাগুলির জন্য, এটি সংখ্যা যুক্ত করার কোড জেনারেট করে।

এটি জাভা স্পেস বলে :

অপারেটরগুলি + এবং -তাদেরকে অ্যাডিটিভ অপারেটর বলা হয়। অ্যাডিটিভএক্সপ্রেসন: মাল্টিপ্লিকটিভেটিস এক্সপ্রেশন

অ্যাডিটিভ অপারেটরগুলির একই প্রাধান্য রয়েছে এবং সিন্ট্যাক্টিকভাবে বাম সংঘবদ্ধ (তারা বাম থেকে ডানে দলবদ্ধ করে)। যদি কোনও +অপারেটরের উভয় অপরেন্ডের ধরণ হয় Stringতবে ক্রিয়াকলাপটি স্ট্রিং কনকেন্টেশন।

অন্যথায়, অপারেটরের প্রতিটি অপারেন্ডের +প্রকারটি অবশ্যই এমন এক প্রকারের হতে হবে যা রূপান্তরযোগ্য (§5.1.8) আদিম সংখ্যার প্রকারে, অথবা একটি সংকলন-সময় ত্রুটি ঘটে।

প্রতিটি ক্ষেত্রে, বাইনারি -অপারেটরের প্রতিটি অপারেন্ডের প্রকারটি অবশ্যই এমন এক প্রকারের হতে হবে যা রূপান্তরযোগ্য (§5.1.8) আদিম সংখ্যার প্রকারে, অথবা একটি সংকলন-সময় ত্রুটি ঘটে।


7
অনুমানের উদ্ধৃতিটি এই প্রশ্নের সাথে মোটেই প্রাসঙ্গিক নয়।
আর্নেস্ট ফ্রেডম্যান-পার্বত্য

এটি এক্সট্রাক্ট "যদি একটি + অপারেটরের উভয় অপরেনডের ধরণ স্ট্রিং হয় তবে ক্রিয়াকলাপটি স্ট্রিং কনটেনটেশন হয় Otherwise ) একটি আদিম সংখ্যার প্রকারে, বা একটি সংকলন-সময় ত্রুটি ঘটে "" আপনি দয়া করে বলতে পারেন কেন এটি প্রাসঙ্গিক নয়।
রমেশ পিভিকে

7
এটি কীভাবে বাস্তবায়ন হয়েছে সে সম্পর্কে এটি কিছুই বলছে না, যা প্রশ্ন। আমি মনে করি পোস্টারটি ইতিমধ্যে বুঝতে পারে যে বৈশিষ্ট্যটি বিদ্যমান।
আর্নেস্ট ফ্রেডম্যান-হিল

14

স্ট্রিং ক্লাস কীভাবে অপারেটরকে ওভাররাইড করে?

এটা হয় না। সংকলক এটি করে। কঠোরভাবে বলতে গেলে, সংকলক স্ট্রিং অপারেন্ডগুলির জন্য + অপারেটরটিকে ওভারলোড করে।


6

সবার আগে (+) ওভাররাইড নয় ওভাররাইড হয়

জাভা ভাষা স্ট্রিং কনটেনটেশন অপারেটর (+) এর জন্য বিশেষ সমর্থন সরবরাহ করে, যা জাভা স্ট্রিংজ অবজেক্টের জন্য ওভারলোড করা হয়েছে।

  1. বাম হাতের অপারেন্ড যদি স্ট্রিং হয় তবে এটি কনটেনটেশন হিসাবে কাজ করে।

  2. বাম হাতের অপারেন্ডটি পূর্ণসংখ্যা হলে এটি অতিরিক্ত অপারেটরের হিসাবে কাজ করে


3
(২) বাম অপারেন্ডটি যদি একটি পূর্ণসংখ্যা হয় তবে এটিতে স্বয়ংক্রিয়ভাবে আনবক্স করা থাকে intএবং তার পরে জাভার সাধারণ নিয়ম প্রয়োগ হয়।
লার্নের মারকুইস

2
উদ্ধৃতিটির নীচে দেওয়া দুটি বিধিগুলি ভুল: আমি বিশ্বাস করি সেগুলি হওয়া উচিত: দুটি আদিম (বা আনবক্সেবল ক্লাস) = সংযোজন; কমপক্ষে একটি স্ট্রিং =
কনটেনটেশন

4

জাভা ভাষা স্ট্রিং কনকেনটেশন অপারেটর (+) এবং অন্যান্য বস্তুর স্ট্রিংয়ে রূপান্তর করার জন্য বিশেষ সহায়তা সরবরাহ করে। StringBuilder(বা StringBuffer) শ্রেণি এবং এর appendপদ্ধতির মাধ্যমে স্ট্রিং কনটেনটেশন প্রয়োগ করা হয় ।


4

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

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

সুতরাং, নীতিগতভাবে, "সংযোজন" অবজেক্টগুলির "যুক্ত" হওয়ার প্রকৃতির উপর নির্ভর করে। জাভা এটিকে স্ট্রিংয়ের পাশাপাশি ইনটস এবং ফ্লোটস (লম্বা, ডাবলস, ...) এর জন্য সংজ্ঞা দেয়


3

+অপারেটর সাধারণত একটি দ্বারা প্রতিস্থাপিত হয় StringBuilderসময় সঙ্কলন করেন। এই বিষয়ে আরও তথ্যের জন্য এই উত্তরটি দেখুন।


যদি এটি হয় তবে স্ট্রিংবিল্ডার জনসাধারণের ব্যবহারের জন্য আদৌ বিদ্যমান থাকার কোনও কারণ আছে কি? +অপারেটর দ্বারা প্রতিস্থাপিত হয় না এমন কোন মামলা আছে StringBuilder?
সেমরে

2
আপনি যে প্রশ্নটি জিজ্ঞাসা করতে চান তা হ'ল "কেন অপারেটর জনসাধারণের ব্যবহারের জন্য একেবারেই বিদ্যমান?", কারণ এখানে ঘৃণা হয়। আপনার অন্যান্য প্রশ্ন হিসাবে, আমি এটি ঠিক জানি না, তবে আমি অনুমান করব যে এরকম কোনও ঘটনা নেই।
বৃশ্চিক

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