জাভা ক্লাসে ক্যানোনিকাল নাম, সাধারণ নাম এবং শ্রেণীর নামের মধ্যে পার্থক্য কী?


972

জাভাতে, এইগুলির মধ্যে পার্থক্য কী:

Object o1 = ....
o1.getClass().getSimpleName();
o1.getClass().getName();
o1.getClass().getCanonicalName();

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



218
আমি মনে করি এটি একটি যুক্তিসঙ্গত প্রশ্ন। জাভাদোক তিনটির মধ্যে পার্থক্য ব্যাখ্যা করার জন্য একটি ভাল কাজ করে না।
গ্রাহাম বোরল্যান্ড

1
দেখুন - docs.oracle.com/javase/6/docs/api/java/lang/Class.html অথবা সম্ভবত কেবল একটি পরীক্ষা লিখুন।
নিক হল্ট

7
@ গ্রাহামবোরল্যান্ড জাভাডোক "জাভা ল্যাঙ্গুয়েজ স্পেসিফিকেশন দ্বারা নির্ধারিত হিসাবে" বলেছেন - যাতে আপনি এটি নথিতে সন্ধান করতে পারেন। এটি ক্লিকযোগ্য লিঙ্ক নয় বলেই লোকেরা এখনও সর্বনিম্ন প্রচেষ্টা করতে পারে এবং প্রথম অনুসন্ধান ইঞ্জিনের ফলাফলটিতে ক্লিক করতে পারে।
vbence

66
@ ভ্যাবেন্স: বেশিরভাগ লোকেরা এ জাতীয় তুচ্ছ জিনিসের জন্য জেএলএস অনুসন্ধান করার চেয়ে বরং কাজগুলি সম্পন্ন করতে পারে। অতএব, এটি প্রথম গুগলের ফলাফল :)
পথিক্রিত

উত্তর:


1129

আপনি যদি কিছু সম্পর্কে অনিশ্চিত হন তবে প্রথমে একটি পরীক্ষা লেখার চেষ্টা করুন।

আমি এটা করেছি:

class ClassNameTest {
    public static void main(final String... arguments) {
        printNamesForClass(
            int.class,
            "int.class (primitive)");
        printNamesForClass(
            String.class,
            "String.class (ordinary class)");
        printNamesForClass(
            java.util.HashMap.SimpleEntry.class,
            "java.util.HashMap.SimpleEntry.class (nested class)");
        printNamesForClass(
            new java.io.Serializable(){}.getClass(),
            "new java.io.Serializable(){}.getClass() (anonymous inner class)");
    }

    private static void printNamesForClass(final Class<?> clazz, final String label) {
        System.out.println(label + ":");
        System.out.println("    getName():          " + clazz.getName());
        System.out.println("    getCanonicalName(): " + clazz.getCanonicalName());
        System.out.println("    getSimpleName():    " + clazz.getSimpleName());
        System.out.println("    getTypeName():      " + clazz.getTypeName()); // added in Java 8
        System.out.println();
    }
}

ছাপে:

int.class (আদিম):
    getName (): int
    getCanonicalName (): int
    getSimpleName (): int
    getTypeName (): int

স্ট্রিং.ক্লাস (সাধারণ শ্রেণি):
    getName (): java.lang.String
    getCanonicalName (): java.lang.String
    getSimpleName (): স্ট্রিং
    getTypeName (): java.lang.String

java.util.HashMap.SimpleEntry.class (নেস্টেড ক্লাস):
    getName (): java.util.AbstractMap $ সিম্পল ইন্ট্রি
    getCanonicalName (): java.util.AbstractMap.SimpleEntry
    getSimpleName (): সিম্পল ইন্ট্রি
    getTypeName (): java.util.AbstractMap $ সিম্পল ইন্ট্রি

নতুন java.io.Serializable ()} get। getClass () (বেনামে অভ্যন্তর শ্রেণি):
    getName (): ClassNameTest $ 1
    getCanonicalName (): নাল
    getSimpleName ():    
    getTypeName (): ClassNameTest $ 1

সর্বশেষ ব্লকে একটি খালি প্রবেশ রয়েছে যেখানে getSimpleNameখালি স্ট্রিংটি ফিরে আসে।

এটির উপর নজর দেওয়া হচ্ছে:

  • নাম যে নামটি পরিবর্তনশীল সঙ্গে বর্গ, উদাহরণস্বরূপ, একটি কলে লোড করতে ব্যবহার করতে চাই হয় Class.forNameডিফল্ট সঙ্গে ClassLoader। একটি নির্দিষ্ট ক্ষেত্রের মধ্যে ClassLoader, সমস্ত শ্রেণীর অনন্য নাম রয়েছে।
  • প্রামাণ্য নামটি নাম একটি আমদানি বিবৃতিতে ব্যবহার করা হবে হয়। এটি toStringলগিং অপারেশনের সময় বা কার্যকর হতে পারে । যখন javacসংকলকটির ক্লাসপথের সম্পূর্ণ দর্শন আছে, এটি সংকলনের সময় সম্পূর্ণরূপে যোগ্য শ্রেণিবদ্ধ এবং প্যাকেজের নামগুলির সংঘর্ষের মাধ্যমে এর মধ্যে প্রচলিত নামগুলির স্বতন্ত্রতা প্রয়োগ করে। তবে জেভিএমগুলিকে অবশ্যই এই জাতীয় নাম সংঘর্ষ গ্রহণ করতে হবে, এবং এইভাবে প্রমিত নামগুলি একটি এর মধ্যে শ্রেণি সনাক্ত করতে পারে না ClassLoader। ( getJavaNameপূর্ববর্তী সময়ে, এই প্রাপ্তির আরও ভাল নাম হত ; তবে এই পদ্ধতিটি এমন এক সময় থেকে এসেছে যখন জেভিএম কেবল জাভা প্রোগ্রামগুলি চালানোর জন্য ব্যবহৃত হত।)
  • সহজ নাম ঢিলেঢালাভাবে সময় আবার, বর্গ চিহ্নিত সহায়ক হতে পারে toStringবা লগিং অপারেশন কিন্তু অনন্য হতে নিশ্চিত করা হয় না।
  • টাইপ নাম আয়, "এটা) toString (মত: এটা বিশুদ্ধরূপে তথ্যপূর্ণ এবং কোনো চুক্তি মূল্য আছে" "এই ধরনের নামের জন্য একটি তথ্যপূর্ণ স্ট্রিং" (যেমন sir4ur0n দ্বারা লিখিত)

5
আপনি কি অতিরিক্ত প্রয়োজন মনে করেন?
নিক হল্ট

2
@ অনুপমসাইনি হ্যাঁ সত্যিকারের অ্যাপ্লিকেশনটিতে এই জাতীয় প্যাকেজের নাম থাকা পাগল হবে।
জেইন

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

2
@ পিটারডিয়েবি কীভাবে? আপনার যা যা জানা দরকার তা হ'ল আপনি যে পদ্ধতিটির নাম পরীক্ষা করতে চান তা।
বোকা জেসুস

20
জাভা 8 যোগ করা হয়েছে getTypeName () পাশাপাশি ... আপডেট করার জন্য যত্ন?
থিওডোর মুরডক

90

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

package com.example;

public final class TestClassNames {
    private static void showClass(Class<?> c) {
        System.out.println("getName():          " + c.getName());
        System.out.println("getCanonicalName(): " + c.getCanonicalName());
        System.out.println("getSimpleName():    " + c.getSimpleName());
        System.out.println("toString():         " + c.toString());
        System.out.println();
    }

    private static void x(Runnable r) {
        showClass(r.getClass());
        showClass(java.lang.reflect.Array.newInstance(r.getClass(), 1).getClass()); // Obtains an array class of a lambda base type.
    }

    public static class NestedClass {}

    public class InnerClass {}

    public static void main(String[] args) {
        class LocalClass {}
        showClass(void.class);
        showClass(int.class);
        showClass(String.class);
        showClass(Runnable.class);
        showClass(SomeEnum.class);
        showClass(SomeAnnotation.class);
        showClass(int[].class);
        showClass(String[].class);
        showClass(NestedClass.class);
        showClass(InnerClass.class);
        showClass(LocalClass.class);
        showClass(LocalClass[].class);
        Object anonymous = new java.io.Serializable() {};
        showClass(anonymous.getClass());
        showClass(java.lang.reflect.Array.newInstance(anonymous.getClass(), 1).getClass()); // Obtains an array class of an anonymous base type.
        x(() -> {});
    }
}

enum SomeEnum {
   BLUE, YELLOW, RED;
}

@interface SomeAnnotation {}

এটি সম্পূর্ণ আউটপুট:

getName():          void
getCanonicalName(): void
getSimpleName():    void
toString():         void

getName():          int
getCanonicalName(): int
getSimpleName():    int
toString():         int

getName():          java.lang.String
getCanonicalName(): java.lang.String
getSimpleName():    String
toString():         class java.lang.String

getName():          java.lang.Runnable
getCanonicalName(): java.lang.Runnable
getSimpleName():    Runnable
toString():         interface java.lang.Runnable

getName():          com.example.SomeEnum
getCanonicalName(): com.example.SomeEnum
getSimpleName():    SomeEnum
toString():         class com.example.SomeEnum

getName():          com.example.SomeAnnotation
getCanonicalName(): com.example.SomeAnnotation
getSimpleName():    SomeAnnotation
toString():         interface com.example.SomeAnnotation

getName():          [I
getCanonicalName(): int[]
getSimpleName():    int[]
toString():         class [I

getName():          [Ljava.lang.String;
getCanonicalName(): java.lang.String[]
getSimpleName():    String[]
toString():         class [Ljava.lang.String;

getName():          com.example.TestClassNames$NestedClass
getCanonicalName(): com.example.TestClassNames.NestedClass
getSimpleName():    NestedClass
toString():         class com.example.TestClassNames$NestedClass

getName():          com.example.TestClassNames$InnerClass
getCanonicalName(): com.example.TestClassNames.InnerClass
getSimpleName():    InnerClass
toString():         class com.example.TestClassNames$InnerClass

getName():          com.example.TestClassNames$1LocalClass
getCanonicalName(): null
getSimpleName():    LocalClass
toString():         class com.example.TestClassNames$1LocalClass

getName():          [Lcom.example.TestClassNames$1LocalClass;
getCanonicalName(): null
getSimpleName():    LocalClass[]
toString():         class [Lcom.example.TestClassNames$1LocalClass;

getName():          com.example.TestClassNames$1
getCanonicalName(): null
getSimpleName():    
toString():         class com.example.TestClassNames$1

getName():          [Lcom.example.TestClassNames$1;
getCanonicalName(): null
getSimpleName():    []
toString():         class [Lcom.example.TestClassNames$1;

getName():          com.example.TestClassNames$$Lambda$1/1175962212
getCanonicalName(): com.example.TestClassNames$$Lambda$1/1175962212
getSimpleName():    TestClassNames$$Lambda$1/1175962212
toString():         class com.example.TestClassNames$$Lambda$1/1175962212

getName():          [Lcom.example.TestClassNames$$Lambda$1;
getCanonicalName(): com.example.TestClassNames$$Lambda$1/1175962212[]
getSimpleName():    TestClassNames$$Lambda$1/1175962212[]
toString():         class [Lcom.example.TestClassNames$$Lambda$1;

সুতরাং, এখানে বিধি আছে। প্রথমে আদিম প্রকারগুলি এবং এর সাথে শুরু করা যাক void:

  1. যদি শ্রেণীর অবজেক্টটি কোনও আদিম ধরণের প্রতিনিধিত্ব করে বা void, চারটি পদ্ধতিই কেবল তার নামটি দেয়।

এখন getName()পদ্ধতির জন্য নিয়ম :

  1. প্রতিটি নন-ল্যাম্বদা এবং নন-অ্যারে শ্রেণি বা ইন্টারফেসের (অর্থাত্ শীর্ষ স্তরের, নেস্টেড, অভ্যন্তরীণ, স্থানীয় এবং বেনামে) একটি নাম থাকে (যা দিয়ে ফিরে আসে getName()) প্যাকেজের নাম যা একটি বিন্দুর পরে থাকে (যদি কোনও প্যাকেজ থাকে) ), সংকলক দ্বারা উত্পাদিত হিসাবে তার শ্রেণি-ফাইলের নাম অনুসারে (প্রত্যয় ছাড়া .class)। যদি কোনও প্যাকেজ না থাকে তবে এটি কেবল শ্রেণি-ফাইলের নাম। ক্লাসটি যদি অভ্যন্তরীণ, নেস্টেড, স্থানীয় বা বেনাম শ্রেণি হয় তবে সংকলকটি $তার শ্রেণি-ফাইলের নামটিতে কমপক্ষে একটি উত্পন্ন করতে হবে। নোট করুন যে বেনামে ক্লাসের জন্য, ক্লাসের নামটি ডলার-সাইন দিয়ে শেষ হবে তার পরে একটি সংখ্যা।
  2. লাম্বদা শ্রেণীর নামগুলি সাধারণত অনির্দেশ্য, এবং যাইহোক আপনার সেগুলির যত্ন নেওয়া উচিত নয়। হুবহু, তাদের নামটি বদ্ধ শ্রেণীর নাম, তার $$Lambda$পরে একটি সংখ্যা, তারপরে একটি স্ল্যাশ এবং তার পরে অন্য নম্বর।
  3. প্রিমিটিভের বর্গ বর্ণনাকারী হয় Zজন্য boolean, Bজন্য byte, Sজন্য short, Cজন্য char, Iজন্য int, Jজন্য long, Fজন্য floatএবং Dজন্য double। অ্যারেবিহীন ক্লাস এবং ইন্টারফেসের জন্য শ্রেণীর বিবরণকারী যা Lঅনুসরণ করে তা getName()অনুসরণ করে ;। অ্যারে শ্রেণীর জন্য, শ্রেণীর বিবরণকারীটির [পরে উপাদান উপাদান (যা নিজেই অন্য একটি অ্যারে শ্রেণি হতে পারে) এর শ্রেণি বর্ণনাকারী অনুসরণ করে।
  4. অ্যারে ক্লাসগুলির জন্য, getName()পদ্ধতিটি তার শ্রেণীর বর্ণনাকারীকে ফেরত দেয়। এই নিয়মটি কেবল অ্যারে শ্রেণীর ক্ষেত্রেই ব্যর্থ বলে মনে হচ্ছে যার উপাদান উপাদানটি ল্যাম্বডা (সম্ভবত সম্ভবত এটি বাগ), তবে আশা করি এটি যেভাবেই হওয়া উচিত নয় কারণ এমন অ্যারে শ্রেণীর অস্তিত্বেরও কোনও বিন্দু নেই যার উপাদানগুলির একটি ল্যাম্বদা।

এখন, toString()পদ্ধতি:

  1. শ্রেণীর উদাহরণটি যদি একটি ইন্টারফেস (বা একটি টিকা, যা একটি বিশেষ ধরণের ইন্টারফেস) প্রতিনিধিত্ব করে, তবে toString()প্রত্যাবর্তন "interface " + getName()। এটি যদি কোনও আদিম হয়, তবে এটি সহজভাবে ফিরে আসে getName()। যদি এটি অন্য কিছু হয় (একটি শ্রেণীর ধরণের, এমনকি এটি বেশ বিচিত্র হলেও), এটি ফিরে আসে "class " + getName()

getCanonicalName()পদ্ধতি:

  1. শীর্ষ-স্তরের শ্রেণি এবং ইন্টারফেসের জন্য, getCanonicalName()পদ্ধতিটি কী getName()ফিরে আসে তার পদ্ধতিটি ফিরে আসে।
  2. getCanonicalName()পদ্ধতি আয় nullবেনামী বা স্থানীয় শ্রেণীর জন্য এবং যারা অ্যারে শ্রেণীর জন্য।
  3. অভ্যন্তরীণ এবং নেস্টেড ক্লাস এবং ইন্টারফেসের জন্য, getCanonicalName()পদ্ধতিটি getName()বিন্দু দ্বারা সংকলক-প্রবর্তিত ডলার-চিহ্নগুলি প্রতিস্থাপনের পদ্ধতিটি কী করে তা ফিরিয়ে দেয় ।
  4. অ্যারে ক্লাসগুলির জন্য, উপাদানটি প্রকারের নামটির নাম থাকলে getCanonicalName()পদ্ধতিটি ফিরে আসে । অন্যথায়, এটি উপাদান টাইপ দ্বারা অনুসৃত প্রামাণ্য নামটি ফেরৎ ।nullnull[]

getSimpleName()পদ্ধতি:

  1. শীর্ষ স্তরের, নেস্টেড, অভ্যন্তরীণ এবং স্থানীয় শ্রেণীর জন্য, getSimpleName()উত্স ফাইলে লিখিত হিসাবে শ্রেণীর নামটি প্রদান করে।
  2. বেনাম ক্লাসের জন্য getSimpleName()রিটার্ন খালি দেয় String
  3. ল্যাম্বদা ক্লাসের জন্য প্যাকেজের নাম ছাড়া getSimpleName()কী getName()ফিরে আসবে তা কেবল ফেরত দেয় । এটি খুব বেশি অর্থবোধ করে না এবং আমার কাছে বাগের মতো দেখায়, তবে getSimpleName()ল্যাম্বডা ক্লাসটি শুরু করার কোনও আহ্বান নেই ।
  4. অ্যারে ক্লাসের জন্য getSimpleName()পদ্ধতিটি অনুসরণ করে উপাদান শ্রেণীর সাধারণ নাম দেয় []। এটিতে মজাদার / অদ্ভুত পার্শ্ব-প্রতিক্রিয়া রয়েছে যা অ্যারে ক্লাসগুলির উপাদানগুলির নাম একটি বেনাম শ্রেণীর []তাদের সাধারণ নামগুলির মতোই।

2
… replacing the dollar-signs by dots: কেবলমাত্র ডলারের চিহ্ন যা ডিলিমিটর হিসাবে চালু হয়েছিল তা প্রতিস্থাপন করা হচ্ছে। কোনও সাধারণ নামের অংশ হিসাবে আপনার কাছে ডলার থাকতে পারে এবং সেগুলি স্থানে থাকবে।
এমভিজি

ওহ না! অংশ হিসাবে ক্লাস নাম! আমি একটি ক্লাস ট্রান্সফর্মার বিকাশ করছি এবং আমি ভেবেছিলাম যে '/' ক্লাস এবং প্যাকেজের নামের মধ্যে একটি নিরাপদ ডিলিমিটার হবে: /
জোসে রবার্তো আরাজো জনিয়ার

81

নিক হল্টের পর্যবেক্ষণ ছাড়াও, আমি Arrayডেটা টাইপের জন্য কয়েকটি কেস চালিয়েছি:

//primitive Array
int demo[] = new int[5];
Class<? extends int[]> clzz = demo.getClass();
System.out.println(clzz.getName());
System.out.println(clzz.getCanonicalName());
System.out.println(clzz.getSimpleName());       

System.out.println();


//Object Array
Integer demo[] = new Integer[5]; 
Class<? extends Integer[]> clzz = demo.getClass();
System.out.println(clzz.getName());
System.out.println(clzz.getCanonicalName());
System.out.println(clzz.getSimpleName());

উপরে কোড স্নিপেট প্রিন্ট:

[I
int[]
int[]

[Ljava.lang.Integer;
java.lang.Integer[]
Integer[]

28
উপরের উত্তরের একটি সম্পাদনার প্রস্তাব দেওয়ার চেয়ে আরও ভাল আমি চাই না।
লোকি

17

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

নিম্নলিখিত উদাহরণ বিবেচনা করুন:

package a.b;
class C {
  static class D extends C {
  }
  D d;
  D[] ds;
}
  • সহজ নাম এর Dহয় D। ক্লাস ঘোষণার সময় আপনি কেবল এটিই লিখেছিলেন। বেনাম শ্রেণীর কোনও সাধারণ নাম নেই। Class.getSimpleName()এই নামটি বা খালি স্ট্রিং প্রদান করে। $আপনি যদি এ জাতীয় লেখেন তবে সাধারণ নামটি অন্তর্ভুক্ত করা সম্ভব , যেহেতু জেএলএস বিভাগ ৩.৮$ অনুসারে কোনও শনাক্তকারীর বৈধ অংশ এটি (এমনকি কিছুটা নিরুৎসাহিত হলেও)।

  • মতে JLS অধ্যায় 6.7 উভয় a.b.C.Dএবং a.b.C.D.D.Dহবে পুরোপুরি যোগ্যতাসম্পন্ন নাম , কিন্তু শুধুমাত্র a.b.C.Dহবে প্রামাণ্য নামটি এর D। সুতরাং প্রতিটি আধ্যাত্মিক নাম একটি সম্পূর্ণরূপে যোগ্য নাম, তবে কনভার্সটি সবসময় সত্য হয় না। Class.getCanonicalName()ক্যানোনিকাল নামটি ফিরে আসবে বা null

  • Class.getName()জেএলএস বিভাগ 13.1-এ উল্লিখিত বাইনারি নামটি ফেরত দেওয়ার জন্য নথিভুক্ত করা হয়েছে । এই ক্ষেত্রে এটি জন্য এবং জন্য ফিরে আসে ।a.b.C$DD[La.b.C$D;D[]

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

  • বেনামে ক্লাস এবং স্থানীয় ক্লাসগুলির কোনও সম্পূর্ণ যোগ্য নাম নেই তবে এখনও একটি বাইনারি নাম রয়েছে । ক্লাসের জন্য একই ক্লাসের ভিতরে নেস্টেড থাকে। প্রত্যেক শ্রেণীর একটি বাইনারি নাম রয়েছে।

  • চলমান javap -v -privateউপর a/b/C.classঅনুষ্ঠান বাইটকোড ধরণ বোঝায় dযেমন La/b/C$D;এবং অ্যারে যে dsযেমন [La/b/C$D;। এগুলিকে বর্ণনাকারী বলা হয় এবং এগুলি জেভিএমএস বিভাগে উল্লেখ করা হয়েছে ৪.৩

  • এই a/b/C$Dউভয় বর্ণনাকারীর জন্য ব্যবহৃত শ্রেণীর নাম বাইনারি নাম দ্বারা প্রতিস্থাপন .করে যা পাবেন get /জেভিএম স্পষ্টত স্পষ্টতই এটিকে বাইনারি নামের অভ্যন্তরীণ রূপ বলেজেভিএমএস বিভাগ ৪.২.১ এটি বর্ণনা করে এবং উল্লেখ করেছে যে বাইনারি নাম থেকে পার্থক্যটি historicalতিহাসিক কারণে ছিল।

  • ফাইলের নাম টিপিক্যাল ফাইলের নাম ভিত্তিক শ্রেণী লোডার এক একটি বর্গ কি যদি আপনি ব্যাখ্যা পাবেন /একটি ডিরেক্টরি বিভাজক হিসেবে বাইনারি নামের অভ্যন্তরীণ আকারে, এবং ফাইলের নাম এক্সটেনশন যোগ .classএটি। এটি প্রশ্নযুক্ত শ্রেণীর লোডার দ্বারা ব্যবহৃত শ্রেণীর পথের তুলনায় সমাধান হয়েছে।


3
এটি গ্রহণযোগ্য উত্তর হওয়া উচিত কারণ এটিই একমাত্র উত্তর যা জেএলএসকে উল্লেখ করে এবং সঠিক পরিভাষা ব্যবহার করে।
জন

10

এটি getName (), getSimpleName (), getCanonicalName () বর্ণনা করার সাথে পাওয়া সেরা দস্তাবেজ

https://javahowtodoit.wordpress.com/2014/09/09/java-lang-class-what-is-the-difference-between-class-getname-class-getcanonicalname-and-class-getsimplename/

// Primitive type
int.class.getName();          // -> int
int.class.getCanonicalName(); // -> int
int.class.getSimpleName();    // -> int

// Standard class
Integer.class.getName();          // -> java.lang.Integer
Integer.class.getCanonicalName(); // -> java.lang.Integer
Integer.class.getSimpleName();    // -> Integer

// Inner class
Map.Entry.class.getName();          // -> java.util.Map$Entry
Map.Entry.class.getCanonicalName(); // -> java.util.Map.Entry
Map.Entry.class.getSimpleName();    // -> Entry     

// Anonymous inner class
Class<?> anonymousInnerClass = new Cloneable() {}.getClass();
anonymousInnerClass.getName();          // -> somepackage.SomeClass$1
anonymousInnerClass.getCanonicalName(); // -> null
anonymousInnerClass.getSimpleName();    // -> // An empty string

// Array of primitives
Class<?> primitiveArrayClass = new int[0].getClass();
primitiveArrayClass.getName();          // -> [I
primitiveArrayClass.getCanonicalName(); // -> int[]
primitiveArrayClass.getSimpleName();    // -> int[]

// Array of objects
Class<?> objectArrayClass = new Integer[0].getClass();
objectArrayClass.getName();          // -> [Ljava.lang.Integer;
objectArrayClass.getCanonicalName(); // -> java.lang.Integer[]
objectArrayClass.getSimpleName();    // -> Integer[]

3

এটা যে খেয়াল করা খুবই মজার getCanonicalName()এবং getSimpleName()বাড়াতে পারেন InternalErrorযখন বর্গ নাম বিকৃত। এটি জাভা-বিহীন কিছু JVM ভাষার ক্ষেত্রে ঘটে, যেমন, স্কালা।

নিম্নলিখিতটি বিবেচনা করুন (জাভা 8-তে স্কেল 2.11):

scala> case class C()
defined class C

scala> val c = C()
c: C = C()

scala> c.getClass.getSimpleName
java.lang.InternalError: Malformed class name
  at java.lang.Class.getSimpleName(Class.java:1330)
  ... 32 elided

scala> c.getClass.getCanonicalName
java.lang.InternalError: Malformed class name
  at java.lang.Class.getSimpleName(Class.java:1330)
  at java.lang.Class.getCanonicalName(Class.java:1399)
  ... 32 elided

scala> c.getClass.getName
res2: String = C

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


1
    public void printReflectionClassNames(){
    StringBuffer buffer = new StringBuffer();
    Class clazz= buffer.getClass();
    System.out.println("Reflection on String Buffer Class");
    System.out.println("Name: "+clazz.getName());
    System.out.println("Simple Name: "+clazz.getSimpleName());
    System.out.println("Canonical Name: "+clazz.getCanonicalName());
    System.out.println("Type Name: "+clazz.getTypeName());
}

outputs:
Reflection on String Buffer Class
Name: java.lang.StringBuffer
Simple Name: StringBuffer
Canonical Name: java.lang.StringBuffer
Type Name: java.lang.StringBuffer

1
পদ্ধতির অভ্যন্তরে প্রথম দুটি লাইন হ্রাস করা যেতে পারেClass<StringBuffer> clazz = StringBuffer.class
ThePyroEagle

1

getName () - এই শ্রেণীর অবজেক্টের দ্বারা স্ট্রিং হিসাবে উপস্থাপিত সত্তার (শ্রেণি, ইন্টারফেস, অ্যারে শ্রেণি, আদিম ধরণের বা নামটি প্রদান করে।

getCanonicalName () - জাভা ল্যাঙ্গুয়েজ স্পেসিফিকেশন দ্বারা সংজ্ঞায়িত অন্তর্নিহিত শ্রেণীর প্রমিত নামটি দেয়।

getSimpleName () - অন্তর্নিহিত শ্রেণীর সাধারণ নামটি দেয়, সোর্স কোডে এটি দেওয়া নাম।

package com.practice;

public class ClassName {
public static void main(String[] args) {

  ClassName c = new ClassName();
  Class cls = c.getClass();

  // returns the canonical name of the underlying class if it exists
  System.out.println("Class = " + cls.getCanonicalName());    //Class = com.practice.ClassName
  System.out.println("Class = " + cls.getName());             //Class = com.practice.ClassName
  System.out.println("Class = " + cls.getSimpleName());       //Class = ClassName
  System.out.println("Class = " + Map.Entry.class.getName());             // -> Class = java.util.Map$Entry
  System.out.println("Class = " + Map.Entry.class.getCanonicalName());    // -> Class = java.util.Map.Entry
  System.out.println("Class = " + Map.Entry.class.getSimpleName());       // -> Class = Entry 
  }
}

একটি পার্থক্য হ'ল আপনি যদি একটি বেনাম শ্রেণি ব্যবহার করেন ক্লাস ব্যবহার করেন তবে ক্লাসের নাম ব্যবহার করার চেষ্টা করার সময় আপনি নাল মান পেতে পারেনgetCanonicalName()

আরেকটি সত্য হ'ল অভ্যন্তরীণ শ্রেণীর জন্য পদ্ধতির getName()চেয়ে getCanonicalName()পদ্ধতিটি আলাদাভাবে আচরণ করে ।getName()এনক্লোজিং ক্লাস ক্যানোনিকাল নাম এবং অভ্যন্তর শ্রেণীর সরল নামের মধ্যে বিভাজক হিসাবে ডলার ব্যবহার করে।

জাভাতে একটি শ্রেণীর নাম পুনরুদ্ধার সম্পর্কে আরও জানার জন্য ।

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