উদাহরণস্বরূপ এবং Class.isAssignableFrom (…) এর মধ্যে পার্থক্য কী?


457

নিচের কোনটি ভাল?

a instanceof B

অথবা

B.class.isAssignableFrom(a.getClass())

আমি কেবল যে পার্থক্যটি জানি তা হ'ল, যখন 'এ' নਾਲ হয়, প্রথমটি মিথ্যা দেয়, দ্বিতীয়টি ব্যতিক্রম ছুঁড়ে দেয়। তা ছাড়া তারা কি সর্বদা একই ফল দেয়?


17
রেকর্ডগুলির জন্য, আইন্সট্যান্স () হ'ল একটি বস্তুকে শ্রেণীর ধরণের মধ্যে কাস্ট করা যায় কিনা তা যাচাই করার জন্য সবচেয়ে সুবিধাজনক পদ্ধতি (আরও তথ্যের জন্য দেখুন: tshikatshikaa.blogspot.nl/2012/07/… )
জের্মে ভার্সেটেঞ্জ

উত্তর:


497

ব্যবহার করার সময় instanceof, আপনাকে Bসংকলন সময়ে ক্লাসটি জানতে হবে । isAssignableFrom()এটি ব্যবহার করার সময় গতিশীল এবং রানটাইমের সময় পরিবর্তন হতে পারে।


12
আমি এটি পাই না - কেন আমরা লিখতে পারি না তা দয়া করে বিস্তারিত বলুন a instanceof Bref.getClass()। এত অল্প ব্যাখ্যা দিয়ে (বা এর অভাব) কীভাবে এটি গ্রহণযোগ্য উত্তর হতে পারে?
এলিরান মালকা

65
সিনট্যাক্স হয় a instanceof Brefনা a instanceof Bref.class। উদাহরণস্বরূপ অপারেটরের দ্বিতীয় তর্কটি একটি শ্রেণীর নাম, কোনও শ্রেণীর অবজেক্টের দৃষ্টান্তের সাথে সমাধান করা কোনও অভিব্যক্তি নয়।
ব্র্যান্ডন ব্লুম

2
হ্যাঁ "গতিশীল" বলতে না গিয়ে :) পারফরম্যান্স ব্যতীত, এটি একটি সত্য পার্থক্য।
পিটার্ক

2
@ ইলিরানমালকা হয়ত আপনার ক্লাস থাকতে পারে যা রানটাইমে তৈরি হয়েছিল। প্রক্সি বস্তুর মতো Like
ওয়াগনার সুছিয়া

সুতরাং, ইন B.class.isAssignableFrom(a.getClass())বি পরিচিত, এবং a instanceof Bআরও ভাল। রাইট?
ফ্লোরিয়ান এফ

208

instanceofপ্রারম্ভিক ধরণের নয়, কেবলমাত্র রেফারেন্স ধরণের সাথে ব্যবহার করা যেতে পারে। isAssignableFrom()যে কোনও শ্রেণীর অবজেক্টের সাথে ব্যবহার করা যেতে পারে:

a instanceof int  // syntax error
3 instanceof Foo  // syntax error
int.class.isAssignableFrom(int.class)  // true

দেখা http://java.sun.com/javase/6/docs/api/java/lang/Class.html#isAssignableFrom(java.lang.Class)


10
আদিম ধরণের সাথে উদাহরণস্বরূপ / isAssignableFrom ব্যবহার করার বিন্দুটি আমি দেখতে পাচ্ছি না।
জিমি টি।

116

পারফরম্যান্সের বিচারে:

টি এল; ডিআর

আইস ইনস্ট্যান্স বা উদাহরণস্বরূপ ব্যবহার করুন যা একই রকম পারফরম্যান্স করে। #SignignFrom সামান্য ধীর।

সম্পাদনা অনুসারে বাছাই করা:

  1. isInstance
  2. উদাহরণস্বরূপ (+ 0.5%)
  3. isAignignableFrom (+ 2.7%)

20 ওয়ার্মআপ পুনরাবৃত্তি সহ জাভা 8 উইন্ডোজ এক্স 64 এ 2000 পুনরাবৃত্তির মানদণ্ডের উপর ভিত্তি করে।

ধারণায়

বাইটকোড দর্শকের মতো নরম ব্যবহার করে আমরা প্রতিটি অপারেটরকে বাইটকোডে অনুবাদ করতে পারি।

এর প্রেক্ষাপটে:

package foo;

public class Benchmark
{
  public static final Object a = new A();
  public static final Object b = new B();

  ...

}

জাভা:

b instanceof A;

বাইটকোড:

getstatic foo/Benchmark.b:java.lang.Object
instanceof foo/A

জাভা:

A.class.isInstance(b);

বাইটকোড:

ldc Lfoo/A; (org.objectweb.asm.Type)
getstatic foo/Benchmark.b:java.lang.Object
invokevirtual java/lang/Class isInstance((Ljava/lang/Object;)Z);

জাভা:

A.class.isAssignableFrom(b.getClass());

বাইটকোড:

ldc Lfoo/A; (org.objectweb.asm.Type)
getstatic foo/Benchmark.b:java.lang.Object
invokevirtual java/lang/Object getClass(()Ljava/lang/Class;);
invokevirtual java/lang/Class isAssignableFrom((Ljava/lang/Class;)Z);

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

মানদণ্ড

ক্রেডিট: @ অ্যালেক্সান্দ্র-ডাবিনস্কি পরামর্শ দিয়েছেন এবং বেস কোড সরবরাহ করার জন্য @ ইউুরাকে ধন্যবাদ, এখানে একটি জেএমএইচ বেঞ্চমার্ক রয়েছে (এই টিউনিং গাইডটি দেখুন ):

class A {}
class B extends A {}

public class Benchmark {

    public static final Object a = new A();
    public static final Object b = new B();

    @Benchmark
    @BenchmarkMode(Mode.Throughput)
    @OutputTimeUnit(TimeUnit.MICROSECONDS)
    public boolean testInstanceOf()
    {
        return b instanceof A;
    }

    @Benchmark
    @BenchmarkMode(Mode.Throughput)
    @OutputTimeUnit(TimeUnit.MICROSECONDS)
    public boolean testIsInstance()
    {
        return A.class.isInstance(b);
    }

    @Benchmark
    @BenchmarkMode(Mode.Throughput)
    @OutputTimeUnit(TimeUnit.MICROSECONDS)
    public boolean testIsAssignableFrom()
    {
        return A.class.isAssignableFrom(b.getClass());
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(TestPerf2.class.getSimpleName())
                .warmupIterations(20)
                .measurementIterations(2000)
                .forks(1)
                .build();

        new Runner(opt).run();
    }
}

নিম্নলিখিত ফলাফল দিয়েছেন (স্কোর একটি একক ইউনিটের বেশ কয়েকটি ক্রিয়াকলাপ , সুতরাং স্কোরটি আরও ভাল):

Benchmark                       Mode   Cnt    Score   Error   Units
Benchmark.testIsInstance        thrpt  2000  373,061 ± 0,115  ops/us
Benchmark.testInstanceOf        thrpt  2000  371,047 ± 0,131  ops/us
Benchmark.testIsAssignableFrom  thrpt  2000  363,648 ± 0,289  ops/us

সতর্কতা

  • মানদণ্ডটি জেভিএম এবং প্ল্যাটফর্ম নির্ভর। যেহেতু প্রতিটি অপারেশনের মধ্যে কোনও উল্লেখযোগ্য পার্থক্য নেই, তাই বিভিন্ন জাভা সংস্করণ এবং / অথবা সোলারিস, ম্যাক বা লিনাক্সের মতো প্ল্যাটফর্মগুলিতে আলাদা ফলাফল (এবং সম্ভবত ভিন্ন ক্রম!) পাওয়া সম্ভব হতে পারে।
  • বেঞ্চমার্কটি "বি বি এ এর ​​একটি উদাহরণ" এর পারফরম্যান্সের সাথে তুলনা করে যখন "বি" এটিকে প্রসারিত করে সরাসরি "। শ্রেণীর শ্রেণিবিন্যাস যদি আরও গভীর এবং আরও জটিল হয় (যেমন বি প্রসারিত এক্স যা Y প্রসারিত করে যা জেড প্রসারিত করে যা A প্রসারিত করে), ফলাফলগুলি ভিন্ন হতে পারে।
  • সাধারণত অপারেটরগুলির মধ্যে একটি বাছাই করার কোডটি প্রথমে লেখার পরামর্শ দেওয়া হয় (সর্বাধিক সুবিধাজনক) এবং তারপরে কোনও কার্যকারিতা বাধা আছে কিনা তা পরীক্ষা করতে আপনার কোডটি প্রোফাইল করুন profile হতে পারে এই অপারেটরটি আপনার কোডের প্রেক্ষাপটে নগণ্য, বা হতে পারে ...
  • পূর্ববর্তী পয়েন্টের সাথে সম্পর্কিত, instanceofআপনার কোডের প্রসঙ্গে isInstanceউদাহরণের চেয়ে আরও সহজেই অনুকূলিত হয়ে উঠতে পারে ...

আপনাকে উদাহরণ দেওয়ার জন্য, নিম্নলিখিত লুপটি নিন:

class A{}
class B extends A{}

A b = new B();

boolean execute(){
  return A.class.isAssignableFrom(b.getClass());
  // return A.class.isInstance(b);
  // return b instanceof A;
}

// Warmup the code
for (int i = 0; i < 100; ++i)
  execute();

// Time it
int count = 100000;
final long start = System.nanoTime();
for(int i=0; i<count; i++){
   execute();
}
final long elapsed = System.nanoTime() - start;

জেআইটি-কে ধন্যবাদ, কোডটি এক পর্যায়ে অনুকূলিত হয়েছে এবং আমরা পেয়েছি:

  • উদাহরণস্বরূপ: 6 এসএমএস
  • isInstance: 12ms
  • isAignignableFrom: 15ms

বিঃদ্রঃ

প্রকৃতপক্ষে এই পোস্টটি নিজস্ব বেঞ্চমার্ক একটি ব্যবহার করছেন জন্য কাঁচা জাভা লুপ, যা ঠিক সময়ে মত কিছু অপ্টিমাইজেশান লুপ বাদ দিতে পারে যেমন অবিশ্বস্ত ফলাফল দিলেন। সুতরাং এটি বেশিরভাগই পরিমাপ করছিল যে লুটের অনুকূলকরণ করতে জেআইটি সংকলকটি কতটা সময় নিয়েছিল: আরও তথ্যের জন্য পুনরাবৃত্তির সংখ্যার চেয়ে পারফরম্যান্স টেস্ট দেখুন

সম্পর্কিত প্রশ্নাবলী


6
হ্যাঁ, instanceofএকটি বাইটকোড যা মূলত একই যুক্তি checkcast(কাস্টিংয়ের পিছনে বাইটকোড) ব্যবহার করে। এটি জেআইটিসি অপ্টিমাইজেশনের ডিগ্রি নির্বিশেষে অন্যান্য বিকল্পগুলির থেকে সহজাতভাবে দ্রুত হবে।
হট লিকস

1
যা বোধগম্য হয়, যেমন isAssignableFrom()গতিশীল।
ম্যাথিউউ

হ্যাঁ, জেএমএইচ ফলাফলগুলি সম্পূর্ণ আলাদা (সকলের জন্য একই গতি)।
ইউরা

হাই, দুর্দান্ত বেঞ্চমার্ক, সবেমাত্র এমন একটি পরিস্থিতিতে দৌড়ে গেল যেখানে isignableFrom কে হাজারবার ডাকা হত, উদাহরণস্বরূপ পরিবর্তন করে আসলেই একটি পার্থক্য তৈরি হয়েছিল। এই উত্তরটি কোথাও একটি ব্লগ পোস্টের জন্য মূল্যবান হবে ...;)
মার্টিন

33

একটি আরো সরাসরি সমতুল্য a instanceof Bহয়

B.class.isInstance(a)

এই কাজ (রিটার্ন মিথ্যা) যখন aহয় nullখুব।


দুর্দান্ত, তবে এটি প্রশ্নের উত্তর দেয় না এবং একটি মন্তব্য করা উচিত ছিল।
ম্যাডব্রেকস

23

উপরে বর্ণিত মৌলিক পার্থক্যগুলি ছাড়াও ক্লাসে উদাহরণস্বরূপ অপারেটর এবং isAignignFrom পদ্ধতির মধ্যে একটি মূল সূক্ষ্ম পার্থক্য রয়েছে।

পড়ুন instanceofযেমন "এই (বাম অংশ) হয় (ডান অংশ) এই দৃষ্টান্ত বা এই কোন উপশ্রেণী" এবং পড়া x.getClass().isAssignableFrom(Y.class)হিসাবে "ক্যান আমি লিখি X x = new Y()"। অন্য কথায়, উদাহরণস্বরূপ অপারেটর চেক করে যে বাম বস্তুটি সমান বা ডান শ্রেণীর সাবক্লাস, isAssignableFromযদি পরীক্ষা করা হয় তবে আমরা প্যারামিটার ক্লাসের অবজেক্টটি নির্ধারণ করতে পারি কিনা (যা থেকে) পদ্ধতিটি বলা হয়।
নোট করুন যে এই দু'টিই প্রকৃত উদাহরণ বিবেচনা করে রেফারেন্স ধরণের নয়।

A, B এবং C শ্রেণীর 3 টি উদাহরণ বিবেচনা করুন যেখানে C এবং B এবং B বিস্তৃত হয় A.

B b = new C();

System.out.println(b instanceof A); //is b (which is actually class C object) instance of A, yes. This will return true.  
System.out.println(b instanceof B); // is b (which is actually class C object) instance of B, yes. This will return true.  
System.out.println(b instanceof C); // is b (which is actually class C object) instance of C, yes. This will return true. If the first statement would be B b = new B(), this would have been false.
System.out.println(b.getClass().isAssignableFrom(A.class));//Can I write C c = new A(), no. So this is false.
System.out.println(b.getClass().isAssignableFrom(B.class)); //Can I write C c = new B(), no. So this is false.
System.out.println(b.getClass().isAssignableFrom(C.class)); //Can I write C c = new C(), Yes. So this is true.

3
b instanceof Aএর সমতুল্য A.class.isAssignableFrom(b.getClass())(যেমন ওপি লক্ষ্য করেছে)। আপনার উদাহরণটি সঠিক তবে অপ্রাসঙ্গিক।
করু

যেহেতু বিমূর্ত বা জনসাধারণের ডিফল্ট নির্মাতা ব্যতীত new Y()আইনী নাও হতে পারে Y, তাই আপনি X x = (Y)nullযদি সঠিক হন এবং কেবল x.getClass().isAssignableFrom(Y.class)সত্য হয় তা বলতে পারেন ।
আর্থ ইঞ্জিন

2
এই উদাহরণে কেন 'বি .ক্লাস' (?। IsAignignFrom (A.class))? আমার ধারণা উদাহরণটি A.class.isAignignableFrom (b.getClass ()) এর বিপরীত হওয়া উচিত।
লোশাদ ভিটপকাঃ

14

আরও একটি পার্থক্য রয়েছে:

এক্স নাল উদাহরণস্বরূপ false তা বিচার্য নয়

null.getClass ()। isAignignableFrom (X) একটি নালপয়েন্টার এক্সেকশন নিক্ষেপ করবে


4
-1, ভুল: null instanceof X(যেখানে সংকলনের সময় এক্স কিছু শ্রেণি হিসাবে পরিচিত) সর্বদা ফিরে আসবে false
ক্যাস্পার

4
@ ক্যাস্পার আপনি সঠিক হওয়ার সময়, প্রাথমিক ধারণাটি একটি ভাল বিষয় ছিল। আমি পোস্টটি সম্পাদনা করেছি যাতে এটি সঠিক হয়।
এরিকসন

1
এটি সহায়ক, প্রান্তের ক্ষেত্রে সর্বদা গুরুত্বপূর্ণ is
ট্রিলিয়নস

প্রথম লাইনের সমতুল্য হতে, দ্বিতীয় লাইনটি হওয়া X.class.isAssignableFrom(null.getClass())উচিত? তবে হ্যাঁ, getClass()নাল রেফারেন্সে কল করার ফলে এনপিই হবে।
উইলিয়াম দাম

এই উত্তরটি এই বিন্দুটিকে মিস করে - একটি নাল ডিসেফারেন্স প্রাসঙ্গিক নয় কারণ অপারেশনটির বাইরে ব্যর্থতা ঘটে (আপনি এরকম কোনও রেফারেন্স ব্যবহার করার আগে আপনাকে সর্বদা নাল পরীক্ষা করা দরকার)। সাধারণভাবে প্রথম স্থানে getClass()ব্যবহার করা উচিত নয় isAssignableFrom- অপারেশনটি কোনও বস্তু না থাকার পরিস্থিতির জন্য বোঝানো হয়। আপনি অবজেক্ট রেফারেন্স থাকে a, ব্যবহার a instanceof SomeClass(যদি আপনি না টাইপ জানেন SomeClass) অথবা someObject.getClass().isInstance(a)(যদি আপনি না ধরণ জানেন someObject)।
অ্যান্ড্রুএফ

12

আরও একটি পার্থক্য আছে। যদি পরীক্ষার জন্য (শ্রেণি) টাইপটি গতিশীল হয়, উদাহরণস্বরূপ কোনও পদ্ধতি প্যারামিটার হিসাবে পাস করা হয়, তবে উদাহরণস্বরূপ এটি আপনার জন্য কাটবে না।

boolean test(Class clazz) {
   return (this instanceof clazz); // clazz cannot be resolved to a type.
}

তবে আপনি এটি করতে পারেন:

boolean test(Class clazz) {
   return (clazz.isAssignableFrom(this.getClass())); // okidoki
}

উফ, আমি দেখছি এই উত্তরটি ইতিমধ্যে কভার করা আছে। এই উদাহরণটি কারও পক্ষে সহায়ক।


3
আসলে কোন উত্তর সত্যই সঠিক নয় - কাজযোগ্য ডাব্লু / ক্লাস থেকে কাজযোগ্য, Class.isInstance হচ্ছে 'উদাহরণস্বরূপ'
বেলা

@ বেসটেসের সঠিক মন্তব্যটিকে কংক্রিট কোডে রাখার জন্য: কারণ আপনার একটি বিষয় রয়েছে ( this), clazz.isInstance(this)আপনার উদাহরণে আরও ভাল।
অ্যান্ড্রুএফ

7

এই থ্রেডটি আমাকে কীভাবে instanceofপৃথক করেছে তার কিছুটা অন্তর্দৃষ্টি দিয়েছিল isAssignableFrom, তাই আমি ভেবেছিলাম যে আমি নিজের কিছু ভাগ করব।

আমি এটি ব্যবহার করে খুঁজে পেয়েছি isAssignableFrom একমাত্র শ্রেণিটির রেফারেন্স অন্য শ্রেণীর উদাহরণ নিতে পারে, তবে যখন কারও সাথে তুলনা না করার উদাহরণ রয়েছে তখন নিজেকে জিজ্ঞাসা করার একমাত্র (সম্ভবত একমাত্র নয়, সম্ভবত সবচেয়ে সহজ) উপায় way

অতএব, আমি instanceofঅপারেটরটি অ্যাসাইনবিলিটি তুলনা করতে ভাল ধারণা হিসাবে খুঁজে পাইনি যখন আমার সমস্ত ক্লাস ছিল, যদি না আমি ক্লাসগুলির মধ্যে একটির থেকে উদাহরণ তৈরি করার চিন্তা না করি; আমি ভেবেছিলাম এই হবে।


5

উদাহরণটি আদিম ধরণের বা জেনেরিক প্রকারের সাথে ব্যবহার করা যায় না। নিম্নলিখিত কোড হিসাবে:

//Define Class< T > type ... 

Object e = new Object();

if(e instanceof T) {
  // Do something.
}

ত্রুটিটি হ'ল: প্যারামিটার টি টাইপের বিরুদ্ধে চেক পরীক্ষা করতে পারবেন না instead এর পরিবর্তে এর ক্ষয়কারী অবজেক্টটি ব্যবহার করুন কারণ আরও জেনেরিক ধরণের তথ্য রানটাইমে মুছে ফেলা হবে।

রানটাইম রেফারেন্স অপসারণ করে টাইপ মুছে ফেলার কারণে সংকলন করে না। তবে নীচের কোডটি সংকলন করবে:

if( type.isAssignableFrom(e.getClass())){
  // Do something.
}

4

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

... A.class.isAignignFFrom (obj.getClass ()) ...

অথবা

... আপত্তি উদাহরণ এ ...

তবে isAignignFrom সমাধানের জন্য এখানে আপত্তিটির ধরণটি দৃশ্যমান হওয়া দরকার। যদি এটি না হয় (উদাঃ, আপত্তিটির ধরণটি কোনও ব্যক্তিগত অভ্যন্তর শ্রেণীর হতে পারে), এই বিকল্পটি বাইরে is তবে উদাহরণস্বরূপ সমাধানটি সর্বদা কার্যকর হবে work


2
ওটা সত্যি না. দয়া করে "আদম Rosenfield" মন্তব্য দেখুন stackoverflow.com/questions/496928/...
বচন Veksler

1
আপনি কি "এটি সত্য নয়" বিস্তারিত বর্ণনা করতে পারেন? আপনি যে মন্তব্যটি উল্লেখ করেছেন তার আমার পোস্টের দৃশ্যের সাথে কোনও সম্পর্ক নেই। আমার কাছে এমন কিছু টেস্ট কোড রয়েছে যা আমার ব্যাখ্যাকে ব্যাক আপ করে।
বীজগণিত

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

0
isAssignableFrom(A, B) =

if (A == B) return true
else if (B == java.lang.Object) return false
else return isAssignableFrom(A, getSuperClass(B))

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


2
এই কোডটি কী করে এবং কীভাবে এটি প্রশ্নের উত্তর দেয় দয়া করে তা ব্যাখ্যা করুন।
ফান্ড মনিকার লকসুইট

0

পারফরম্যান্স "2" (জেএমএইচ সহ) এর সাথে কথা বলছি:

class A{}
class B extends A{}

public class InstanceOfTest {

public static final Object a = new A();
public static final Object b = new B();

@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public boolean testInstanceOf()
{
    return b instanceof A;
}

@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public boolean testIsInstance()
{
    return A.class.isInstance(b);
}

@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public boolean testIsAssignableFrom()
{
    return A.class.isAssignableFrom(b.getClass());
}

public static void main(String[] args) throws RunnerException {
    Options opt = new OptionsBuilder()
            .include(InstanceOfTest.class.getSimpleName())
            .warmupIterations(5)
            .measurementIterations(5)
            .forks(1)
            .build();

    new Runner(opt).run();
}
}

এটি দেয়:

Benchmark                            Mode  Cnt  Score   Error  Units
InstanceOfTest.testInstanceOf        avgt    5  1,972 ? 0,002  ns/op
InstanceOfTest.testIsAssignableFrom  avgt    5  1,991 ? 0,004  ns/op
InstanceOfTest.testIsInstance        avgt    5  1,972 ? 0,003  ns/op

সুতরাং আমরা এই উপসংহারে আসতে পারি যে: instanceof যত দ্রুত isInstance () এবং isAssignableFrom () না দূরে (+ + 0.9% executon সময়)। সুতরাং আপনি যা পছন্দ করুন কোনও আসল পার্থক্য নেই


0

এটি কার্যকরভাবে দেখানোর জন্য কয়েকটি উদাহরণ সম্পর্কে কীভাবে ...

@Test
public void isInstanceOf() {
    Exception anEx1 = new Exception("ex");
    Exception anEx2 = new RuntimeException("ex");
    RuntimeException anEx3 = new RuntimeException("ex");

    //Base case, handles inheritance
    Assert.assertTrue(anEx1 instanceof Exception);
    Assert.assertTrue(anEx2 instanceof Exception);
    Assert.assertTrue(anEx3 instanceof Exception);

    //Other cases
    Assert.assertFalse(anEx1 instanceof RuntimeException);
    Assert.assertTrue(anEx2 instanceof RuntimeException);
    Assert.assertTrue(anEx3 instanceof RuntimeException);
}

@Test
public void isAssignableFrom() {
    Exception anEx1 = new Exception("ex");
    Exception anEx2 = new RuntimeException("ex");
    RuntimeException anEx3 = new RuntimeException("ex");

    //Correct usage = The base class goes first
    Assert.assertTrue(Exception.class.isAssignableFrom(anEx1.getClass()));
    Assert.assertTrue(Exception.class.isAssignableFrom(anEx2.getClass()));
    Assert.assertTrue(Exception.class.isAssignableFrom(anEx3.getClass()));

    //Incorrect usage = Method parameter is used in the wrong order
    Assert.assertTrue(anEx1.getClass().isAssignableFrom(Exception.class));
    Assert.assertFalse(anEx2.getClass().isAssignableFrom(Exception.class));
    Assert.assertFalse(anEx3.getClass().isAssignableFrom(Exception.class));
}

-2

আমাদের দলে আমরা কিছু পরীক্ষা করেছি যা তার A.class.isAssignableFrom(B.getClass())চেয়ে দ্রুত কাজ করে B instanceof A। আপনার যদি এটি প্রচুর পরিমাণে উপাদানগুলিতে পরীক্ষা করতে হয় তবে এটি খুব কার্যকর হতে পারে।


13
এইচএম, আপনার যদি কোনও বাধা থাকে তবে instanceofআমি বিশ্বাস করি আপনার ডিজাইনের মারাত্মক সমস্যা রয়েছে ...
স্লেসকে ২

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