రిఫ్లెక్షన్ API దేనికి?

జావా రిఫ్లెక్షన్ మెకానిజం డెవలపర్‌ను మార్పులు చేయడానికి మరియు తరగతులు, ఇంటర్‌ఫేస్‌లు, ఫీల్డ్‌లు మరియు పద్ధతుల గురించి వాటి పేర్లు తెలియకుండా రన్‌టైమ్‌లో సమాచారాన్ని పొందేందుకు అనుమతిస్తుంది.

రిఫ్లెక్షన్ API మిమ్మల్ని కొత్త ఆబ్జెక్ట్‌లను, కాల్ మెథడ్స్‌ని సృష్టించడానికి మరియు ఫీల్డ్ విలువలను పొందడానికి లేదా సెట్ చేయడానికి మిమ్మల్ని అనుమతిస్తుంది.

ప్రతిబింబాన్ని ఉపయోగించి మీరు చేయగలిగే ప్రతిదాని జాబితాను తయారు చేద్దాం:

  • వస్తువు యొక్క తరగతిని గుర్తించండి/నిశ్చయించండి
  • క్లాస్ మాడిఫైయర్‌లు, ఫీల్డ్‌లు, పద్ధతులు, స్థిరాంకాలు, కన్‌స్ట్రక్టర్‌లు మరియు సూపర్‌క్లాస్‌ల గురించి సమాచారాన్ని పొందండి
  • అమలు చేయబడిన ఇంటర్‌ఫేస్(లు)కి చెందిన పద్ధతులు ఏవి కనుగొనండి
  • ప్రోగ్రామ్ అమలు చేయబడే వరకు తరగతి పేరు తెలియని తరగతి యొక్క ఉదాహరణను సృష్టించండి
  • పేరు ద్వారా ఉదాహరణ ఫీల్డ్ విలువను పొందండి మరియు సెట్ చేయండి
  • ఒక ఉదాహరణ పద్ధతిని పేరు ద్వారా కాల్ చేయండి

దాదాపు అన్ని ఆధునిక జావా సాంకేతికతలు ప్రతిబింబాన్ని ఉపయోగిస్తాయి. ఇది నేటి జావా / జావా EE ఫ్రేమ్‌వర్క్‌లు మరియు లైబ్రరీలలో చాలా వరకు ఉంది, ఉదాహరణకు:

  • వెబ్ అప్లికేషన్‌లను రూపొందించడానికి స్ప్రింగ్ ఫ్రేమ్‌వర్క్‌లు
  • జూనిట్ టెస్టింగ్ ఫ్రేమ్‌వర్క్

మీరు ఇంతకు ముందెన్నడూ ఈ మెకానిజమ్‌లను ఎదుర్కొని ఉండకపోతే, ఇవన్నీ ఎందుకు అవసరమని మీరు బహుశా అడుగుతున్నారు. సమాధానం చాలా సులభం కానీ చాలా అస్పష్టంగా ఉంది: ప్రతిబింబం నాటకీయంగా వశ్యతను మరియు మా అప్లికేషన్ మరియు కోడ్‌ని అనుకూలీకరించే సామర్థ్యాన్ని పెంచుతుంది.

కానీ ఎల్లప్పుడూ లాభాలు మరియు నష్టాలు ఉన్నాయి. కాబట్టి కొన్ని ప్రతికూలతలను ప్రస్తావిద్దాము:

  • అప్లికేషన్ భద్రత ఉల్లంఘనలు. ప్రతిబింబం మనం చేయకూడని కోడ్‌ని యాక్సెస్ చేయడానికి అనుమతిస్తుంది (ఎన్‌క్యాప్సులేషన్ ఉల్లంఘన).
  • భద్రతా పరిమితులు. రిఫ్లెక్షన్‌కి సెక్యూరిటీ మేనేజర్‌ని నడుపుతున్న సిస్టమ్‌లకు అందుబాటులో లేని రన్‌టైమ్ అనుమతులు అవసరం.
  • తక్కువ పనితీరు. జావాలో ప్రతిబింబం లోడ్ చేయడానికి క్లాస్‌ని కనుగొనడానికి క్లాస్‌పాత్‌ను స్కాన్ చేయడం ద్వారా డైనమిక్‌గా రకాలను నిర్ణయిస్తుంది. ఇది ప్రోగ్రామ్ పనితీరును తగ్గిస్తుంది.
  • నిర్వహించడం కష్టం. ప్రతిబింబాన్ని ఉపయోగించే కోడ్ చదవడం మరియు డీబగ్ చేయడం కష్టం. ఇది తక్కువ అనువైనది మరియు నిర్వహించడం కష్టం.

రిఫ్లెక్షన్ APIని ఉపయోగించి తరగతులతో పని చేస్తోంది

అన్ని ప్రతిబింబ కార్యకలాపాలు java.lang.Class వస్తువుతో ప్రారంభమవుతాయి. ప్రతి రకమైన వస్తువు కోసం, java.lang.Class యొక్క మార్పులేని ఉదాహరణ సృష్టించబడుతుంది. ఇది ఆబ్జెక్ట్ లక్షణాలను పొందడం, కొత్త వస్తువులను సృష్టించడం మరియు కాల్ చేసే పద్ధతులను అందిస్తుంది.

java.lang.Class తో పని చేయడానికి ప్రాథమిక పద్ధతుల జాబితాను చూద్దాం :

పద్ధతి చర్య
స్ట్రింగ్ getName(); తరగతి పేరును అందిస్తుంది
int getModifiers(); యాక్సెస్ మాడిఫైయర్‌లను అందిస్తుంది
ప్యాకేజీ getPackage(); ప్యాకేజీ గురించి సమాచారాన్ని అందిస్తుంది
తరగతి getSuperclass(); పేరెంట్ క్లాస్ గురించి సమాచారాన్ని అందిస్తుంది
తరగతి[] getInterfaces(); ఇంటర్‌ఫేస్‌ల శ్రేణిని అందిస్తుంది
కన్స్ట్రక్టర్[] getConstructors(); క్లాస్ కన్‌స్ట్రక్టర్‌ల గురించి సమాచారాన్ని అందిస్తుంది
ఫీల్డ్స్[] getFields(); తరగతి ఫీల్డ్‌లను అందిస్తుంది
ఫీల్డ్ getField(స్ట్రింగ్ ఫీల్డ్ నేమ్); పేరు ద్వారా తరగతి యొక్క నిర్దిష్ట ఫీల్డ్‌ను అందిస్తుంది
పద్ధతి[] getMethods(); పద్ధతుల శ్రేణిని అందిస్తుంది

తరగతులు, ఇంటర్‌ఫేస్‌లు, ఫీల్డ్‌లు మరియు పద్ధతుల గురించి డేటాను పొందడానికి ఇవి అత్యంత ముఖ్యమైన పద్ధతులు. ఫీల్డ్ విలువలను పొందడానికి లేదా సెట్ చేయడానికి మరియు ప్రైవేట్ ఫీల్డ్‌లను యాక్సెస్ చేయడానికి మిమ్మల్ని అనుమతించే పద్ధతులు కూడా ఉన్నాయి . మేము వాటిని కొంచెం తరువాత చూద్దాం.

ప్రస్తుతం మనం java.lang.Class ని పొందడం గురించి మాట్లాడుతాము . దీన్ని చేయడానికి మాకు మూడు మార్గాలు ఉన్నాయి.

1. Class.forNameని ఉపయోగించడం

నడుస్తున్న అప్లికేషన్‌లో, మీరు తరగతిని పొందడానికి forName(String className) పద్ధతిని తప్పనిసరిగా ఉపయోగించాలి.

ప్రతిబింబాన్ని ఉపయోగించి మనం తరగతులను ఎలా సృష్టించవచ్చో ఈ కోడ్ ప్రదర్శిస్తుంది. మనం పని చేయగల వ్యక్తి తరగతిని సృష్టిద్దాం :

package com.company;

public class Person {
    private int age;
    private String name;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

మరియు మా ఉదాహరణ యొక్క రెండవ భాగం ప్రతిబింబాన్ని ఉపయోగించే కోడ్:

public class TestReflection {
    public static void main(String[] args) {
        try {
            Class<?> aClass = Class.forName("com.company.Person");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

తరగతి యొక్క పూర్తి పేరు తెలిస్తే ఈ విధానం సాధ్యమవుతుంది. అప్పుడు మీరు స్టాటిక్ Class.forName() పద్ధతిని ఉపయోగించి సంబంధిత తరగతిని పొందవచ్చు . ఈ పద్ధతి ఆదిమ రకాల కోసం ఉపయోగించబడదు.

2. .క్లాస్ ఉపయోగించడం

ఒక రకం అందుబాటులో ఉన్నప్పటికీ దానికి ఎటువంటి ఉదాహరణ లేనట్లయితే, మీరు రకం పేరుకు .class జోడించడం ద్వారా తరగతిని పొందవచ్చు. ఆదిమ రకం తరగతిని పొందడానికి ఇది సులభమైన మార్గం.

Class aClass = Person.class;

3. .getClass()ని ఉపయోగించడం

ఆబ్జెక్ట్ అందుబాటులో ఉన్నట్లయితే, తరగతిని పొందడానికి సులువైన మార్గం object.getClass() కి కాల్ చేయడం .

Person person = new Person();
Class aClass = person.getClass();

చివరి రెండు విధానాల మధ్య తేడా ఏమిటి?

కోడింగ్ సమయంలో మీకు ఏ తరగతి వస్తువుపై ఆసక్తి ఉందో మీకు తెలిస్తే A.class ఉపయోగించండి . ఏదైనా ఉదాహరణ అందుబాటులో లేకుంటే, మీరు .classని ఉపయోగించాలి .

తరగతి పద్ధతులను పొందడం

మన తరగతి పద్ధతులను తిరిగి ఇచ్చే పద్ధతులను చూద్దాం: getDeclaredMethods() మరియు getMethods() .

getDeclaredMethods() అనేది పబ్లిక్, ప్రైవేట్, డిఫాల్ట్ మరియు రక్షిత పద్ధతులతో సహా క్లాస్ ఆబ్జెక్ట్ ద్వారా ప్రాతినిధ్యం వహించే క్లాస్ లేదా ఇంటర్‌ఫేస్ యొక్క అన్ని డిక్లేర్డ్ పద్ధతుల కోసం మెథడ్ ఆబ్జెక్ట్‌లను కలిగి ఉన్న శ్రేణిని అందిస్తుంది, కానీ వారసత్వ పద్ధతులు కాదు .

getMethods() క్లాస్ ఆబ్జెక్ట్ ద్వారా ప్రాతినిధ్యం వహించే క్లాస్ లేదా ఇంటర్‌ఫేస్ యొక్క అన్ని పబ్లిక్ పద్ధతుల కోసం మెథడ్ ఆబ్జెక్ట్‌లను కలిగి ఉన్న శ్రేణిని అందిస్తుంది — క్లాస్ లేదా ఇంటర్‌ఫేస్ ద్వారా ప్రకటించబడినవి, అలాగే సూపర్ క్లాస్‌లు మరియు సూపర్ ఇంటర్‌ఫేస్‌ల నుండి సంక్రమించినవి.

వాటిలో ప్రతి ఒక్కటి ఎలా పనిచేస్తుందో చూద్దాం.

getDeclaredMethods() తో ప్రారంభిద్దాం . రెండు పద్ధతుల మధ్య వ్యత్యాసాన్ని అర్థం చేసుకోవడంలో మాకు మళ్లీ సహాయం చేయడానికి, క్రింద మేము వియుక్త సంఖ్యల తరగతితో పని చేస్తాము. మన మెథడ్ శ్రేణిని జాబితా<String> కి మార్చే స్టాటిక్ పద్ధతిని వ్రాద్దాం :

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class TestReflection {
    public static void main(String[] args) {
        final Method[] declaredMethods = Number.class.getDeclaredMethods();
        List<String> actualMethodNames = getMethodNames(declaredMethods);
        actualMethodNames.forEach(System.out::println);
    }

    private static List<String> getMethodNames(Method[] methods) {
        return Arrays.stream(methods)
                .map(Method::getName)
                .collect(Collectors.toList());
    }
}

ఈ కోడ్‌ని అమలు చేయడం వల్ల వచ్చిన ఫలితం ఇక్కడ ఉంది:

byteValue
shortValue
intValue
longValue
ఫ్లోట్ floatValue;
డబుల్ విలువ

ఇవి నంబర్ క్లాస్ లోపల డిక్లేర్డ్ చేయబడిన పద్ధతులు . getMethods() ఏమి అందిస్తుంది? ఉదాహరణలో రెండు పంక్తులను మారుద్దాం:

final Method[] methods = Number.class.getMethods();
List<String> actualMethodNames = getMethodNames(methods);

ఇలా చేయడం ద్వారా, మేము ఈ క్రింది పద్ధతులను చూస్తాము:

byteValue
shortValue
intValue
longValue
ఫ్లోట్ floatValue;
డబుల్‌వాల్యూ
వెయిట్
వెయిట్
వెయిట్ స్ట్రింగ్ హ్యాష్‌కోడ్‌కి
సమానం getClass నోటిఫైఅందరికీ _




అన్ని తరగతులు ఆబ్జెక్ట్‌ను వారసత్వంగా పొందుతాయి కాబట్టి, మా పద్ధతి ఆబ్జెక్ట్ క్లాస్ యొక్క పబ్లిక్ పద్ధతులను కూడా అందిస్తుంది .

తరగతి ఫీల్డ్‌లను పొందడం

తరగతి ఫీల్డ్‌లను పొందడానికి getFields మరియు getDeclaredFields పద్ధతులు ఉపయోగించబడతాయి. ఉదాహరణగా, LocalDateTime తరగతిని చూద్దాం . మేము మా కోడ్‌ని తిరిగి వ్రాస్తాము:

import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class TestReflection {
    public static void main(String[] args) {
        final Field[] declaredFields = LocalDateTime.class.getDeclaredFields();
        List<String> actualFieldNames = getFieldNames(declaredFields);
        actualFieldNames.forEach(System.out::println);
    }

    private static List<String> getFieldNames(Field[] fields) {
        return Arrays.stream(fields)
                .map(Field::getName)
                .collect(Collectors.toList());
    }
}

ఈ కోడ్‌ని అమలు చేయడం వలన, మేము LocalDateTime తరగతిలో ఉన్న ఫీల్డ్‌ల సెట్‌ను పొందుతాము.

MIN
MAX
serialVersionUID
తేదీ
సమయం

మా మునుపటి పద్ధతుల పరీక్షతో సారూప్యతతో, మేము కోడ్‌ను కొద్దిగా మార్చినట్లయితే ఏమి జరుగుతుందో చూద్దాం:

final Field[] fields = LocalDateTime.class.getFields();
List<String> actualFieldNames = getFieldNames(fields);

అవుట్‌పుట్:

MIN
MAX

ఇప్పుడు ఈ పద్ధతుల మధ్య వ్యత్యాసాన్ని గుర్తించండి.

getDeclaredFields పద్ధతి దీని ద్వారా ప్రాతినిధ్యం వహించే క్లాస్ లేదా ఇంటర్‌ఫేస్ ద్వారా ప్రకటించబడిన అన్ని ఫీల్డ్‌ల కోసం ఫీల్డ్ ఆబ్జెక్ట్‌ల శ్రేణిని అందిస్తుందితరగతివస్తువు.

getFields పద్ధతి ద్వారా ప్రాతినిధ్యం వహించే తరగతి లేదా ఇంటర్‌ఫేస్‌లోని అన్ని పబ్లిక్ ఫీల్డ్‌ల కోసం ఫీల్డ్ ఆబ్జెక్ట్‌ల శ్రేణిని అందిస్తుందితరగతివస్తువు.

ఇప్పుడు LocalDateTime లోపల చూద్దాం .

తరగతి యొక్కMINమరియుగరిష్టంగాఫీల్డ్‌లు పబ్లిక్‌గా ఉంటాయి, అంటే అవి getFields పద్ధతి ద్వారా కనిపిస్తాయి . దీనికి విరుద్ధంగా, దితేదీ,సమయం,serialVersionUIDపద్ధతులు ప్రైవేట్ మాడిఫైయర్‌ను కలిగి ఉంటాయి, అంటే అవి getFields పద్ధతి ద్వారా కనిపించవు , కానీ మనం వాటిని getDeclaredFields ఉపయోగించి పొందవచ్చు . ఈ విధంగా మనం ప్రైవేట్ ఫీల్డ్‌ల కోసం ఫీల్డ్ ఆబ్జెక్ట్‌లను యాక్సెస్ చేయవచ్చు.

ఇతర పద్ధతుల వివరణలు

ఇప్పుడు క్లాస్ క్లాస్ యొక్క కొన్ని పద్ధతుల గురించి మాట్లాడాల్సిన సమయం వచ్చింది , అవి:

పద్ధతి చర్య
getModifiers మా తరగతి కోసం మాడిఫైయర్‌లను పొందడం
getPackage మా తరగతిని కలిగి ఉన్న ప్యాకేజీని పొందడం
సూపర్ క్లాస్ పొందండి పేరెంట్ క్లాస్ పొందడం
ఇంటర్‌ఫేస్‌లను పొందండి తరగతి ద్వారా అమలు చేయబడిన ఇంటర్‌ఫేస్‌ల శ్రేణిని పొందడం
getName పూర్తి అర్హత కలిగిన తరగతి పేరును పొందడం
సింపుల్ నేమ్ పొందండి తరగతి పేరు పొందడం

getModifiers()

ఒక ఉపయోగించి మాడిఫైయర్‌లను యాక్సెస్ చేయవచ్చుతరగతివస్తువు.

మాడిఫైయర్‌లు పబ్లిక్ , స్టాటిక్ , ఇంటర్‌ఫేస్ మొదలైన కీలక పదాలు . మేము getModifiers() పద్ధతిని ఉపయోగించి మాడిఫైయర్‌లను పొందుతాము:

Class<Person> personClass = Person.class;
int classModifiers = personClass.getModifiers();

ఈ కోడ్ ఒక విలువను సెట్ చేస్తుందిintఒక బిట్ ఫీల్డ్ వేరియబుల్. ప్రతి యాక్సెస్ మాడిఫైయర్ సంబంధిత బిట్‌ను సెట్ చేయడం లేదా క్లియర్ చేయడం ద్వారా ఆన్ లేదా ఆఫ్ చేయవచ్చు. మేము java.lang.reflect.Modifier క్లాస్‌లోని పద్ధతులను ఉపయోగించి మాడిఫైయర్‌లను తనిఖీ చేయవచ్చు :

import com.company.Person;
import java.lang.reflect.Modifier;

public class TestReflection {
    public static void main(String[] args) {
        Class<Person> personClass = Person.class;
        int classModifiers = personClass.getModifiers();

        boolean isPublic = Modifier.isPublic(classModifiers);
        boolean isStatic = Modifier.isStatic(classModifiers);
        boolean isFinal = Modifier.isFinal(classModifiers);
        boolean isAbstract = Modifier.isAbstract(classModifiers);
        boolean isInterface = Modifier.isInterface(classModifiers);

        System.out.printf("Class modifiers: %d%n", classModifiers);
        System.out.printf("Is public: %b%n", isPublic);
        System.out.printf("Is static: %b%n", isStatic);
        System.out.printf("Is final: %b%n", isFinal);
        System.out.printf("Is abstract: %b%n", isAbstract);
        System.out.printf("Is interface: %b%n", isInterface);
    }
}

మా వ్యక్తి యొక్క ప్రకటన ఎలా ఉందో గుర్తు చేసుకోండి:

public class Person {}

మేము ఈ క్రింది అవుట్‌పుట్‌ను పొందుతాము:

క్లాస్ మాడిఫైయర్‌లు: 1
పబ్లిక్: నిజం
స్టాటిక్: అబద్ధం
చివరిది: తప్పు
అనేది నైరూప్యమైనది: తప్పు
అనేది ఇంటర్‌ఫేస్: తప్పు

మన తరగతిని వియుక్తంగా చేస్తే, మనకు ఇవి ఉంటాయి:

public abstract class Person {}

మరియు ఈ అవుట్‌పుట్:

క్లాస్ మాడిఫైయర్‌లు: 1025
పబ్లిక్: నిజం
స్టాటిక్: అబద్ధం
చివరిది: తప్పు
అనేది నైరూప్యమైనది: ఒప్పు
అనేది ఇంటర్‌ఫేస్: తప్పు

మేము యాక్సెస్ మాడిఫైయర్‌ని మార్చాము, అంటే మాడిఫైయర్ క్లాస్ యొక్క స్టాటిక్ పద్ధతుల ద్వారా తిరిగి వచ్చిన డేటాను కూడా మార్చాము.

getPackage()

ఒక తరగతిని మాత్రమే తెలుసుకుంటే, మేము దాని ప్యాకేజీ గురించి సమాచారాన్ని పొందవచ్చు:

Class<Person> personClass = Person.class;
final Package aPackage = personClass.getPackage();
System.out.println(aPackage.getName());

getSuperclass()

మన దగ్గర క్లాస్ ఆబ్జెక్ట్ ఉంటే, మనం దాని పేరెంట్ క్లాస్‌ని యాక్సెస్ చేయవచ్చు:

public static void main(String[] args) {
    Class<Person> personClass = Person.class;
    final Class<? super Person> superclass = personClass.getSuperclass();
    System.out.println(superclass);
}

మేము బాగా తెలిసిన ఆబ్జెక్ట్ తరగతిని పొందుతాము:

class java.lang.Object

కానీ మా తరగతికి మరొక పేరెంట్ క్లాస్ ఉంటే, మేము దానిని చూస్తాము:

package com.company;

class Human {
    // Some info
}

public class Person extends Human {
    private int age;
    private String name;

    // Some info
}

ఇక్కడ మేము మా పేరెంట్ క్లాస్‌ని పొందుతాము:

class com.company.Human

get Interfaces()

తరగతి ద్వారా అమలు చేయబడిన ఇంటర్‌ఫేస్‌ల జాబితాను మనం ఎలా పొందవచ్చో ఇక్కడ ఉంది:

public static void main(String[] args) {
    Class<Person> personClass = Person.class;
    final Class<?>[] interfaces = personClass.getInterfaces();
    System.out.println(Arrays.toString(interfaces));
}

మరియు మన వ్యక్తి తరగతిని మార్చడం మర్చిపోవద్దు :

public class Person implements Serializable {}

అవుట్‌పుట్:

[ఇంటర్ఫేస్ java.io.Serializable]

ఒక తరగతి అనేక ఇంటర్‌ఫేస్‌లను అమలు చేయగలదు. అందుకే మనకు శ్రేణి వస్తుందితరగతివస్తువులు. జావా రిఫ్లెక్షన్ APIలో, ఇంటర్‌ఫేస్‌లు కూడా సూచించబడతాయితరగతివస్తువులు.

దయచేసి గమనించండి: ఈ పద్ధతి పేర్కొన్న తరగతి ద్వారా అమలు చేయబడిన ఇంటర్‌ఫేస్‌లను మాత్రమే అందిస్తుంది, దాని పేరెంట్ క్లాస్ కాదు. తరగతి ద్వారా అమలు చేయబడిన ఇంటర్‌ఫేస్‌ల పూర్తి జాబితాను పొందడానికి, మీరు ప్రస్తుత తరగతి మరియు వారసత్వ గొలుసులో ఉన్న దాని పూర్వీకులందరినీ సూచించాలి.

getName() & getSimpleName() & getCanonicalName()

ఆదిమ, సమూహ తరగతి, అనామక తరగతి మరియు స్ట్రింగ్ క్లాస్‌తో కూడిన ఉదాహరణను వ్రాద్దాం :

public class TestReflection {
    public static void main(String[] args) {
        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.printf("%s:%n", label);
        System.out.printf("\tgetName()):\t%s%n", clazz.getName());
        System.out.printf("\tgetCanonicalName()):\t%s%n", clazz.getCanonicalName());
        System.out.printf("\tgetSimpleName()):\t%s%n", clazz.getSimpleName());
        System.out.printf("\tgetTypeName():\t%s%n%n", clazz.getTypeName());
    }
}

మా ప్రోగ్రామ్ ఫలితం:

int class (primitive):
getName()): int
getCanonicalName()): int
getSimpleName()): int
getTypeName(): int

String.class (సాధారణ తరగతి):
getName()): java.lang.String
getCanonicalName() ): java.lang.String
getSimpleName()): String
getTypeName(): java.lang.String

java.util.HashMap.SimpleEntry.class (నెస్టెడ్ క్లాస్):
getName()): java.util.AbstractMap$SimpleEntry
getCanonicalName( )): java.util.AbstractMap.SimpleEntry
getSimpleName()): SimpleEntry
getTypeName(): java.util.AbstractMap$SimpleEntry

new java.io.Serializable(){}.getClass() (అనామక అంతర్గత తరగతి):
getName() ): TestReflection$1
getCanonicalName()): శూన్యం
getSimpleName()):
getTypeName(): TestReflection$1

ఇప్పుడు మన ప్రోగ్రామ్ అవుట్‌పుట్‌ను విశ్లేషిద్దాం:

  • getName() ఎంటిటీ పేరును అందిస్తుంది.

  • getCanonicalName() జావా లాంగ్వేజ్ స్పెసిఫికేషన్ ద్వారా నిర్వచించబడిన బేస్ క్లాస్ యొక్క కానానికల్ పేరును అందిస్తుంది. బేస్ క్లాస్‌కు కానానికల్ పేరు లేకుంటే (అంటే, అది స్థానిక లేదా అనామక తరగతి లేదా మూలకం రకానికి నియమానుగుణ పేరు లేని శ్రేణి అయితే) శూన్యతను అందిస్తుంది.

  • getSimpleName() సోర్స్ కోడ్‌లో పేర్కొన్న విధంగా బేస్ క్లాస్ యొక్క సాధారణ పేరును అందిస్తుంది. బేస్ క్లాస్ అనామకంగా ఉంటే ఖాళీ స్ట్రింగ్‌ను అందిస్తుంది.

  • getTypeName() ఈ రకం పేరు కోసం సమాచార స్ట్రింగ్‌ను అందిస్తుంది.