টোস্ট্রিং () এবং হ্যাশকোড () ওভাররাইড করা হলে জাভাতে কোনও সামগ্রীর "অবজেক্ট রেফারেন্স" কীভাবে পাবেন?


106

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

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

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


1
আপনি যদি এটি আদৌ করতে পারেন কিনা তার উপর নির্ভর করে ... == যাওয়ার উপায় ... তবে আমার কাছে কোনও ধারণা নেই যে প্রশ্নে থাকা কোডটি কীভাবে বিদ্ধ হয়। আপনি যা করছেন তার জন্য আবার হ্যাশকোড সম্ভবত ঠিক আছে তবে গ্রন্থাগারটি কীভাবে কার্যকর করা হয় তার উপর নির্ভর করে এটি ভেঙে যেতে পারে।
তোফুবিয়ার

এটি সত্যিই একটি ভাল প্রশ্ন।
ঝাং জিয়াং

উত্তর:


108

আপনি এটির সাথে কী করার পরিকল্পনা করছেন (আপনি যা করতে চান তার সাথে আপনার কল করার প্রয়োজন হবে তার সাথে একটি পার্থক্য আসে)।

hashCode, জাভাডক্সে সংজ্ঞায়িত হিসাবে, বলেছেন:

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

সুতরাং আপনি hashCode()যদি এটি সন্ধানের জন্য ব্যবহার করছেন যে এটি মেমোরিতে কোনও অনন্য বস্তু যা এটি করার পক্ষে ভাল উপায় নয়।

System.identityHashCode নিম্নলিখিতগুলি করে:

ডিফল্ট পদ্ধতি হ্যাশকোড () দ্বারা প্রদত্ত বস্তুর জন্য একই হ্যাশ কোডটি প্রদান করে, প্রদত্ত বস্তুর শ্রেণি হ্যাশকোড () ওভাররাইড করে কিনা whether নাল রেফারেন্সের জন্য হ্যাশ কোডটি শূন্য।

কোনটি, আপনি যা করছেন তার জন্য আপনি কী চান তা শোনাচ্ছে ... তবে আপনি কী করতে চান এটি কীভাবে গ্রন্থাগারটি বাস্তবায়িত হবে তার উপর নির্ভর করে নিরাপদ নাও হতে পারে।


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

1
মতবিরোধগুলি হ'ল এটি সর্বদা আপনি যা চান তা করবে - তবে এটি কিছু ভিএমগুলিতে ভেঙে যেতে পারে।
তোফুবিয়ার

এটি কোনও যুক্তিসঙ্গত ভিএম-এ ভেঙে যাবে (অর্থাত্ হ্যাশকোড অগত্যা অনন্য হবে না)। পরিচয়
হ্যাশকোড

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

"এটি সাধারণত বস্তুর অভ্যন্তরীণ ঠিকানাটিকে পূর্ণসংখ্যার সাথে রূপান্তর করে প্রয়োগ করা হয়" গ্যারান্টি নয়, তবে সূর্যের থেকে ডিফল্ট বাস্তবায়ন। S = "হ্যালো" এবং টি = "হ্যালো" এর মতো জিনিসগুলির ফলাফল সম্ভবত s এবং t একই পরিচয় হ্যাশকোড হিসাবে থাকবে কারণ তারা সত্যই একই জিনিস।
তোফুবিয়ার

50

এইভাবে আমি এটি সমাধান করেছি:

Integer.toHexString(System.identityHashCode(object));

5
এটি আসলে সঠিক নয়, যেহেতু একাধিক অবজেক্ট একই পরিচয় হ্যাশকোড ফিরিয়ে দিতে পারে।
রবিন

2
এটি কি সত্য নয় যে একই পরিচয় হ্যাশ সহ দুটি বস্তু (রেফারেন্স) একই বস্তু? ওপি যা চায় তা
বাসেরো

3
না, এটা সত্য নয়। এটি খুব সম্ভবত, তবে গ্যারান্টিযুক্ত নয় কারণ স্পেকটি অ্যালগরিদমকে সংজ্ঞায়িত করে না।
রবিন

8

==হ্যাশকোড বা সমানগুলির অবজেক্টগুলির প্রয়োগ নির্বিশেষে ডাবল সমান সর্বদা অবজেক্ট পরিচয়ের ভিত্তিতে যাচাই করবে check অবশ্যই - নিশ্চিত করুন যে আপনি যে অবজেক্টের রেফারেন্সের সাথে তুলনা করছেন তা volatile(একটি 1.5+ জেভিএম)।

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

public static java.lang.String identityToString(java.lang.Object object)

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

 ObjectUtils.identityToString(null)         = null
 ObjectUtils.identityToString("")           = "java.lang.String@1e23"
 ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"

1
আপনি যদি জাভা 7 ব্যবহার করে থাকেন তবে আপনার java.util.Objects
noahlz

5

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

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


2

আপনার সমস্ত দৃষ্টান্তে একটি অনন্য আইডি যুক্ত করুন

public interface Idable {
  int id();
}

public class IdGenerator {
  private static int id = 0;
  public static synchronized int generate() { return id++; }
}

public abstract class AbstractSomething implements Idable {
  private int id;
  public AbstractSomething () {
    this.id = IdGenerator.generate();
  }
  public int id() { return id; }
}

অ্যাবস্ট্রাক্টস কিছু থেকে প্রসারিত করুন এবং এই সম্পত্তিটিকে জিজ্ঞাসা করুন। একক ভিএম এর ভিতরে নিরাপদ থাকবে (শ্রেণিবদ্ধদের সাথে স্ট্যাটিক্স পেতে কোনও খেলা খেলছে না এমন ধারণা ধরে) inside


আমি সম্ভবত এই দৃশ্যে অ্যাটমিকিন্টেজারটি ব্যবহার করব - এটির উচ্চতর আউটপুট রয়েছে কারণ সিঙ্ক্রোনাইজেশন প্রয়োজন হয় না এবং এটি প্রদত্ত দেশীয় পারমাণবিক মেমরি অপারেশনগুলি ব্যবহার করেsun.misc.Unsafe
RAnders00

1

স্ট্রিংয়ের রেফারেন্স পেতে আমরা কেবল অবজেক্ট ক্লাসের টস্ট্রিং থেকে কোড অনুলিপি করতে পারি

class Test
{
  public static void main(String args[])
  {
    String a="nikhil";     // it stores in String constant pool
    String s=new String("nikhil");    //with new stores in heap
    System.out.println(Integer.toHexString(System.identityHashCode(a)));
    System.out.println(Integer.toHexString(System.identityHashCode(s)));
  }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.