প্রতিবিম্ব কি এবং কেন এটি দরকারী?


2122

প্রতিবিম্ব কী এবং কেন এটি কার্যকর?

আমি জাভা সম্পর্কে বিশেষভাবে আগ্রহী, তবে আমি ধরে নিই যে কোনও ভাষায় নীতিগুলি একই রকম।


9
আমার জন্য এটি রানটাইমে ক্লাসের নাম পাওয়ার এবং সেই শ্রেণীর অবজেক্ট তৈরি করার একটি উপায়।
নবীন

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


4
@ বিলকের মন্তব্য ছাড়াও: প্রতিবিম্ব খুব শক্তিশালী, আমি এটাকে যাদু বলি। মহান শক্তি দিয়ে মহান দায়িত্ব আসে। আপনি কী করছেন তা যদি আপনি জানেন তবেই এটি ব্যবহার করুন।
এমসি সম্রাট

আপনি ম্যানিফোল্ড ব্যবহার করে প্রতিবিম্বের সাথে জড়িত অনেকগুলি সমস্যা এড়াতে পারেন @Jailbreak। এটি ব্যক্তিগত ক্ষেত্র, পদ্ধতি ইত্যাদিতে সরাসরি, টাইপ-নিরাপদ অ্যাক্সেস সরবরাহ করে the জাভা সংকলক নিরাপদে আপনার কোড যাচাই করুন এবং ম্যানিফোল্ড আপনার জন্য অন্তর্নিহিত প্রতিচ্ছবি অ্যাক্সেস তৈরি করতে দিন। আরও জানুন: manifold.systems/docs.html#type-safe-reflection
স্কট

উত্তর:


1716

নামের প্রতিবিম্বটি কোড বর্ণনার জন্য ব্যবহৃত হয় যা একই সিস্টেমে (বা নিজেই) অন্যান্য কোড পরিদর্শন করতে সক্ষম।

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

সুতরাং, জাভাতে আপনাকে এর একটি কোড উদাহরণ দেওয়ার জন্য (প্রশ্নটিতে থাকা বস্তুর ধারণা করুন foo):

Method method = foo.getClass().getMethod("doSomething", null);
method.invoke(foo, null);

জাভাতে একটি খুব সাধারণ ব্যবহারের ক্ষেত্রে এনটেশন সহ ব্যবহার। উদাহরণস্বরূপ, জুনট 4, @ টেস্ট টীকা সহ ট্যাগ করা পদ্ধতিগুলির জন্য আপনার ক্লাসগুলির সন্ধান করার জন্য প্রতিবিম্বটি ব্যবহার করবে এবং ইউনিট পরীক্ষা চলাকালীন সেগুলি তাদের কল করবে।

আপনাকে http://docs.oracle.com/javase/tutorial/reflect/index.html এ শুরু করার জন্য কয়েকটি ভাল প্রতিচ্ছবি উদাহরণ রয়েছে

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

একটি মন্তব্য থেকে আপডেট:

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


32
আপনি কি দয়া করে এই লাইন পদ্ধতিতে নাল প্যারামিটারটির তাত্পর্যটি কী তা ব্যাখ্যা করতে পারেন পদ্ধতি পদ্ধতি = foo.getClass ()। getMethod ("doSomething", নাল);
কৃষ্ণ চৈতন্য

54
নাল ইঙ্গিত দেয় যে foo পদ্ধতিতে কোনও পরামিতি দেওয়া হচ্ছে না। দেখুন docs.oracle.com/javase/6/docs/api/java/lang/reflect/... , java.lang.Object ... বিস্তারিত জানার জন্য)।
ম্যাট শেপার্ড

791
এটি পরিষ্কার করার জন্য যেহেতু এটির অনেকগুলি প্রচুর পরিমাণে আপত্তি রয়েছে। সিস্টেমে কোডটি পরিদর্শন করার এবং অবজেক্টের ধরণগুলি দেখার ক্ষমতা প্রতিবিম্ব নয়, বরং টাইপ করুন ইন্ট্রোস্পেকশন। প্রতিবিম্বটি হ'ল রান-টাইমে আত্মতন্ত্র ব্যবহার করে পরিবর্তনগুলি করার ক্ষমতা। কিছু ভাষাগুলি অন্তরীক্ষণকে সমর্থন করে বলে এখানে পার্থক্যটি প্রয়োজনীয়, তবে প্রতিবিম্বকে সমর্থন করে না। এরকম একটি উদাহরণ সি ++।
বিগুনটাকান

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

6
@ বিগুনটাকান আপনি কোথা থেকে এই তথ্যটি পেয়েছেন? আমি কেবল রানটাইমে পরিবর্তন করার ক্ষমতাটিই নয় বরং কোনও সামগ্রীর ধরণ দেখার ক্ষমতাও বর্ণনা করার জন্য ওরাকল থেকে সরকারী জাভা ডকুমেন্টেশনে ব্যবহৃত "প্রতিবিম্ব" শব্দটি দেখছি। এমন নয় যে সবচেয়ে তথাকথিত "টাইপ অন্তর্দর্শন" সম্পর্কিত শ্রেণীর উল্লেখ (উদা: Method, Constructor, Modifier, Field, Member, মূলত দৃশ্যত ছাড়া সব Class) মধ্যে হয় java.lang.*reflect*প্যাকেজ। সম্ভবত ধারণা "প্রতিবিম্ব" ব্যাপকভাবে "টাইপ ইন্ট্রোস্পেকশন" এবং রান-টাইমে সংশোধন উভয়কেই অন্তর্ভুক্ত করে?
RestInPeace

246

প্রতিচ্ছবি হ'ল রানটাইমের সময় ক্লাস, পদ্ধতি, বৈশিষ্ট্য ইত্যাদির জন্য পরিদর্শন এবং গতিময়ভাবে কল করার একটি ভাষা।

উদাহরণস্বরূপ, জাভাতে সমস্ত বস্তুর কাছে পদ্ধতি রয়েছে getClass(), যা আপনাকে কম্পাইল করার সময় এটি না জানলেও আপনাকে অবজেক্টের শ্রেণি নির্ধারণ করতে দেয় (উদাহরণস্বরূপ যদি আপনি এটি হিসাবে ঘোষণা করেছেন Object) - এটি তুচ্ছ মনে হতে পারে, তবে এ জাতীয় প্রতিচ্ছবি সম্ভব নয় যেমন কম গতিশীল ভাষায় C++। আরও উন্নত ব্যবহারের সাহায্যে আপনাকে তালিকা পদ্ধতি এবং কল পদ্ধতি, কনস্ট্রাক্টর ইত্যাদি করতে দেয় lets

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

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


2
সুতরাং অন্য কথায়, আপনি এটির যোগ্য নামটির বাইরে একটি উদাহরণ তৈরি করতে পারেন এবং সংকলক এটি সম্পর্কে কোনও অভিযোগ করবেন না (কারণ বলুন আপনি শ্রেণীর নামের জন্য কেবল একটি স্ট্রিং ব্যবহার করেন)। তারপরে, রান সময়ে, সেই শ্রেণিটি উপস্থিত না থাকলে আপনি একটি ব্যতিক্রম পান get আপনি এই ধরনের সংকলককে বাইপাস করেছেন। আপনি কি আমাকে এর জন্য নির্দিষ্ট কিছু ব্যবহারের মামলাটি দিতে পারেন? আমি কখন এটি পছন্দ করব তা আমি ছবিতে পারি না।
ফার্নান্দো গ্যাব্রিয়েলি

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

C++রান টাইম টাইপ তথ্য আছে। RTTI
Ayxan

114

প্রতিবিম্বের আমার প্রিয় ব্যবহারগুলির একটি হ'ল নীচে জাভা ডাম্প পদ্ধতি। এটি কোনও বস্তুকে প্যারামিটার হিসাবে গ্রহণ করে এবং প্রতিটি ক্ষেত্রের নাম এবং মান মুদ্রণ করতে জাভা প্রতিবিম্ব API ব্যবহার করে।

import java.lang.reflect.Array;
import java.lang.reflect.Field;

public static String dump(Object o, int callCount) {
    callCount++;
    StringBuffer tabs = new StringBuffer();
    for (int k = 0; k < callCount; k++) {
        tabs.append("\t");
    }
    StringBuffer buffer = new StringBuffer();
    Class oClass = o.getClass();
    if (oClass.isArray()) {
        buffer.append("\n");
        buffer.append(tabs.toString());
        buffer.append("[");
        for (int i = 0; i < Array.getLength(o); i++) {
            if (i < 0)
                buffer.append(",");
            Object value = Array.get(o, i);
            if (value.getClass().isPrimitive() ||
                    value.getClass() == java.lang.Long.class ||
                    value.getClass() == java.lang.String.class ||
                    value.getClass() == java.lang.Integer.class ||
                    value.getClass() == java.lang.Boolean.class
                    ) {
                buffer.append(value);
            } else {
                buffer.append(dump(value, callCount));
            }
        }
        buffer.append(tabs.toString());
        buffer.append("]\n");
    } else {
        buffer.append("\n");
        buffer.append(tabs.toString());
        buffer.append("{\n");
        while (oClass != null) {
            Field[] fields = oClass.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                buffer.append(tabs.toString());
                fields[i].setAccessible(true);
                buffer.append(fields[i].getName());
                buffer.append("=");
                try {
                    Object value = fields[i].get(o);
                    if (value != null) {
                        if (value.getClass().isPrimitive() ||
                                value.getClass() == java.lang.Long.class ||
                                value.getClass() == java.lang.String.class ||
                                value.getClass() == java.lang.Integer.class ||
                                value.getClass() == java.lang.Boolean.class
                                ) {
                            buffer.append(value);
                        } else {
                            buffer.append(dump(value, callCount));
                        }
                    }
                } catch (IllegalAccessException e) {
                    buffer.append(e.getMessage());
                }
                buffer.append("\n");
            }
            oClass = oClass.getSuperclass();
        }
        buffer.append(tabs.toString());
        buffer.append("}\n");
    }
    return buffer.toString();
}

8
কলকাউন্ট কী সেট করা উচিত?
টম

8
আমি "AWT-ইভেন্টQueue-0" java.lang. থ্রেডে একটি ব্যতিক্রম পেয়েছি I
টম

3
@ টমটি callCountশূন্যে সেট করা উচিত। প্রতিটি মান প্রতিটি আউটপুটের পূর্বে কতগুলি ট্যাব ব্যবহার করা উচিত তা নির্ধারণ করতে এর মান ব্যবহার করা হয়: প্রতিবার ডাম্পকে একটি "সাবোবজেক্ট" ডাম্প করতে হবে, আউটপুটটি প্যারেন্টে নেস্টেড হিসাবে মুদ্রিত হবে। অন্যটি মোড়ানো অবস্থায় সেই পদ্ধতিটি কার্যকর প্রমাণিত হয়। বিবেচনা করুন printDump(Object obj){ System.out.println(dump(obj, 0)); }
fny

1
জাভা.এল.আং.স্ট্যাক ওভারফ্লো এরিয়ারটি চেক না করা পুনরাবৃত্তির কারণে বিজ্ঞপ্তি সংক্রান্ত রেফারেন্সের ক্ষেত্রে তৈরি করা যেতে পারে: বাফার.এপেন্ড (ডাম্প (মান, কলকাউন্ট))
পি

4
আপনি কি বিশেষভাবে আপনার কোডটি পাবলিক ডোমেনে প্রকাশ করতে পারেন, দয়া করে?
স্টলসভিক

84

প্রতিবিম্ব ব্যবহার

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

এক্সটেনসিবিলিটি বৈশিষ্ট্য

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

প্রতিবিম্বের ত্রুটি

প্রতিবিম্ব শক্তিশালী, তবে নির্বিচারে ব্যবহার করা উচিত নয়। যদি প্রতিবিম্বটি ব্যবহার না করেই কোনও অপারেশন করা সম্ভব হয় তবে এটি ব্যবহার না করা ভাল। প্রতিবিম্বের মাধ্যমে কোড অ্যাক্সেস করার সময় নিম্নলিখিত উদ্বেগগুলি মাথায় রাখা উচিত।

  • পারফরম্যান্স ওভারহেড

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

  • সুরক্ষা সীমাবদ্ধতা

প্রতিবিম্বের জন্য রানটাইম অনুমতি প্রয়োজন যা কোনও সুরক্ষা পরিচালকের অধীনে চলার সময় উপস্থিত নাও হতে পারে। কোডের জন্য এটি একটি গুরুত্বপূর্ণ বিবেচনায় যা কোনও অ্যাপলেট হিসাবে সীমাবদ্ধ সুরক্ষা প্রসঙ্গে চালাতে হয়।

  • অভ্যন্তরীণ এক্সপোজার

যেহেতু প্রতিবিম্ব কোডটি এমন অপারেশনগুলি সম্পাদন করতে দেয় যা অ-প্রতিবিম্বিত কোডগুলিতে অবৈধ হবে যেমন ব্যক্তিগত ক্ষেত্র এবং পদ্ধতিগুলি অ্যাক্সেস করার ফলে প্রতিবিম্বের ব্যবহারের ফলে অপ্রত্যাশিত পার্শ্ব-প্রতিক্রিয়া দেখা দিতে পারে যা কোডকে অকার্যকর হতে পারে এবং বহনযোগ্যতা নষ্ট করতে পারে। রিফ্লেক্টিভ কোড বিমূর্ততাগুলিকে ভেঙে দেয় এবং তাই প্ল্যাটফর্মের আপগ্রেডের সাথে আচরণ পরিবর্তন করতে পারে।

উত্স: প্রতিচ্ছবি এপিআই


44

প্রতিবিম্ব এমন একটি মূল প্রক্রিয়া যা কোনও অ্যাপ্লিকেশন বা কাঠামোটিকে কোড সহ কাজ করার অনুমতি দেয় যা সম্ভবত এখনও লেখা হয় নি!

উদাহরণস্বরূপ আপনার সাধারণ ওয়েব.এক্সএমএল ফাইলটি ধরুন। এটিতে সার্লেট উপাদানগুলির একটি তালিকা থাকবে, এতে নেস্টেড সার্লেট-শ্রেণীর উপাদান রয়েছে। সার্ভলেট কন্টেইনারটি ওয়েব.এক্সএমএল ফাইলটি প্রক্রিয়া করবে এবং প্রতিফলনের মাধ্যমে প্রতিটি সার্লেট শ্রেণীর একটি নতুন ইভেন্ট তৈরি করবে।

আর একটি উদাহরণ হ'ল এক্সএমএল পার্সিংয়ের (জাএএক্সপি) জাভা এপিআই । যেখানে কোনও এক্সএমএল পার্সার সরবরাহকারী সুপরিচিত সিস্টেম বৈশিষ্ট্যগুলির মাধ্যমে 'প্লাগ-ইন' করা হয়, যা প্রতিবিম্বের মাধ্যমে নতুন দৃষ্টান্ত তৈরি করতে ব্যবহৃত হয়।

এবং পরিশেষে, সর্বাধিক বিস্তৃত উদাহরণ স্প্রিং যা এর শিম তৈরি করতে এবং এর প্রক্সিগুলির ভারী ব্যবহারের জন্য প্রতিবিম্ব ব্যবহার করে


36

প্রতিটি ভাষা প্রতিবিম্বকে সমর্থন করে না তবে নীতিগুলি সাধারণত যে ভাষাগুলি সমর্থন করে তাদের মধ্যে একই রকম থাকে।

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

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


আমাকে ডিবিতে উপস্থিত তথ্যের ভিত্তিতে অবজেক্টগুলি ইনস্ট্যান্ট করতে হবে। আমি বিশ্বাস করি এটিই আপনি যা বলছেন। নমুনা কোড আমাকে অনেক সাহায্য করবে। আগাম ধন্যবাদ.
এটম

34

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

Class myObjectClass = MyObject.class;
Method[] method = myObjectClass.getMethods();

//Here the method takes a string parameter if there is no param, put null.
Method method = aClass.getMethod("method_name", String.class); 

Object returnValue = method.invoke(null, "parameter-value1");

উপরের উদাহরণে নাল প্যারামিটার হ'ল বস্তু যা আপনি পদ্ধতিটি চালু করতে চান। যদি পদ্ধতিটি স্থির থাকে তবে আপনি নাল সরবরাহ করেন। যদি পদ্ধতিটি স্থিতিশীল না হয় তবে অনুরোধ করার সময় আপনাকে শূন্যের পরিবর্তে একটি বৈধ মাইবজেক্ট উদাহরণ সরবরাহ করতে হবে।

প্রতিচ্ছবি আপনাকে কোনও শ্রেণীর ব্যক্তিগত সদস্য / পদ্ধতিগুলি অ্যাক্সেস করতে দেয়:

public class A{

  private String str= null;

  public A(String str) {
  this.str= str;
  }
}

A obj= new A("Some value");

Field privateStringField = A.class.getDeclaredField("privateString");

//Turn off access check for this field
privateStringField.setAccessible(true);

String fieldValue = (String) privateStringField.get(obj);
System.out.println("fieldValue = " + fieldValue);
  • ক্লাসগুলির পরিদর্শন করার জন্য (অন্তর্মুখী হিসাবেও জানেন) আপনার প্রতিবিম্ব প্যাকেজ আমদানি করতে হবে না java.lang.reflect। শ্রেণীর মেটাডেটা মাধ্যমে অ্যাক্সেস করা যায় java.lang.Class

প্রতিবিম্ব একটি অত্যন্ত শক্তিশালী এপিআই তবে এটি অতিরিক্ত সময়ে ব্যবহৃত হলে অ্যাপ্লিকেশনটি ধীর করতে পারে কারণ এটি রানটাইমের সময়ে সমস্ত ধরণের সমাধান করে।


21

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

প্রতিচ্ছবি ব্যবহার করে দেখতে কেমন তা দেখানোর জন্য একটি দ্রুত জাভা প্রতিবিম্বের উদাহরণ:

Method[] methods = MyObject.class.getMethods();

    for(Method method : methods){
        System.out.println("method = " + method.getName());
    }

এই উদাহরণটি ক্লাস থেকে মাইওবজেক্ট নামে ক্লাসের অবজেক্টটি গ্রহণ করে। শ্রেণীর অবজেক্টটি ব্যবহার করে উদাহরণটি সেই শ্রেণীর পদ্ধতিগুলির একটি তালিকা পায়, পদ্ধতিগুলি পুনরাবৃত্তি করে এবং তাদের নাম মুদ্রণ করে।

ঠিক কিভাবে এই সমস্ত কাজ এখানে ব্যাখ্যা করা হয়

সম্পাদনা : প্রায় 1 বছর পরে আমি এই উত্তরটি সম্পাদনা করছি প্রতিচ্ছবি সম্পর্কে পড়ার সময় আমি প্রতিবিম্বের আরও কয়েকটি ব্যবহার পেয়েছি।

  • বসন্ত শিমের কনফিগারেশন ব্যবহার করে যেমন:


<bean id="someID" class="com.example.Foo">
    <property name="someField" value="someValue" />
</bean>

যখন বসন্তের প্রসঙ্গটি এই <বিন> উপাদানটি প্রক্রিয়া করে, তখন ক্লাসটি ইনস্ট্যান্ট করার জন্য "com.example.Foo" যুক্তি সহ Class.forName (স্ট্রিং) ব্যবহার করবে।

এরপরে এটি <সম্পত্তি> উপাদানটির জন্য উপযুক্ত সেটার পেতে প্রতিবিম্বটি ব্যবহার করবে এবং এর মানটিকে নির্দিষ্ট মানটিতে সেট করবে।

  • জুনিট বিশেষত ব্যক্তিগত / সুরক্ষিত পদ্ধতিগুলির পরীক্ষার জন্য প্রতিচ্ছবি ব্যবহার করে।

ব্যক্তিগত পদ্ধতিগুলির জন্য,

Method method = targetClass.getDeclaredMethod(methodName, argClasses);
method.setAccessible(true);
return method.invoke(targetObject, argObjects);

ব্যক্তিগত ক্ষেত্রের জন্য,

Field field = targetClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);

21

উদাহরণ:

উদাহরণস্বরূপ একটি রিমোট অ্যাপ্লিকেশন গ্রহণ করুন যা আপনার অ্যাপ্লিকেশনটিকে এমন কোনও বস্তু দেয় যা আপনি তাদের API পদ্ধতি ব্যবহার করে পান। এখন অবজেক্টের উপর ভিত্তি করে আপনাকে কিছু ধরণের গণনা সম্পাদন করার প্রয়োজন হতে পারে।

সরবরাহকারী গ্যারান্টি দেয় যে অবজেক্টটি 3 ধরণের হতে পারে এবং আমাদের কী ধরণের অবজেক্টের উপর ভিত্তি করে গণনা করা দরকার।

সুতরাং আমরা 3 টি শ্রেণিতে প্রতিটি আলাদা যুক্তিযুক্ত ধারণায় প্রয়োগ করতে পারি vious সরবরাহকারীর কাছ থেকে প্রাপ্ত বস্তু।


আমারও তেমন কিছু প্রয়োজন .. একটি উদাহরণ আমাকে অনেক সাহায্য করবে কারণ আমি প্রতিচ্ছবি ধারণাগুলির প্রতি নতুন কারণ ..
এটম

2
আমি বিভ্রান্ত: আপনি instanceofরানটাইমে অবজেক্টের ধরণ নির্ধারণ করতে ব্যবহার করতে পারবেন না ?
এনডিএম 13

19

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

public class Test {

    public void firstMoveChoice(){
        System.out.println("First Move");
    } 
    public void secondMOveChoice(){
        System.out.println("Second Move");
    }
    public void thirdMoveChoice(){
        System.out.println("Third Move");
    }

    public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { 
        Test test = new Test();
        Method[] method = test.getClass().getMethods();
        //firstMoveChoice
        method[0].invoke(test, null);
        //secondMoveChoice
        method[1].invoke(test, null);
        //thirdMoveChoice
        method[2].invoke(test, null);
    }

}

18

প্রতিচ্ছবি এমন একটি এপিআই যা রানটাইম সময়ে পদ্ধতি, শ্রেণি, ইন্টারফেসের আচরণ পরীক্ষা বা সংশোধন করতে ব্যবহৃত হয় ।

  1. প্রতিবিম্ব জন্য প্রয়োজনীয় বর্গ অধীন প্রদান করা হয় java.lang.reflect package
  2. প্রতিবিম্ব আমাদের বস্তুটি যার সাথে সম্পর্কিত সেগুলি এবং সেই শ্রেণীর পদ্ধতিগুলি যা অবজেক্টটি ব্যবহার করে কার্যকর করা যায় সে সম্পর্কে তথ্য দেয়।
  3. প্রতিবিম্বের মাধ্যমে আমরা রানটাইমে তাদের সাথে ব্যবহৃত অ্যাক্সেস সুনির্দিষ্ট নির্বিশেষে পদ্ধতিগুলি আহ্বান করতে পারি।

java.langএবং java.lang.reflectপ্যাকেজ জাভা প্রতিফলন ক্লাস প্রদান।

প্রতিবিম্ব সম্পর্কে তথ্য পেতে ব্যবহার করা যেতে পারে -

  1. ক্লাস দ্য getClass()পদ্ধতি বর্গ যা একটি বস্তুর জন্যে নাম পেতে ব্যবহার করা হয়।

  2. কন্সট্রাকটরgetConstructors() পদ্ধতি বর্গ যা একটি বস্তুর জন্যে পাবলিক কনস্ট্রাকটর পেতে ব্যবহার করা হয়।

  3. পদ্ধতিgetMethods() পদ্ধতি বর্গ যা একটি বস্তু জন্যে পাবলিক পদ্ধতি পেতে করতে ব্যবহৃত হয়।

প্রতিফলন এপিআই প্রধানত ব্যবহার করা হয়:

আইডিই (ইন্টিগ্রেটেড ডেভলপমেন্ট এনভায়রনমেন্ট) যেমন: এক্সলিপস, মাইএক্লিপস, নেটবিয়ানস ইত্যাদি
ডিবাগার এবং টেস্ট সরঞ্জাম ইত্যাদি

প্রতিবিম্ব ব্যবহারের সুবিধা:

এক্সটেনসিবিলিটি বৈশিষ্ট্য: কোনও অ্যাপ্লিকেশন তাদের সম্পূর্ণরূপে যোগ্য নাম ব্যবহার করে এক্সটেনসিবিলিটি অবজেক্টগুলির উদাহরণ তৈরি করে বাহ্যিক, ব্যবহারকারী-সংজ্ঞায়িত শ্রেণীর ব্যবহার করতে পারে।

ডিবাগিং এবং পরীক্ষার সরঞ্জামগুলি: ডিবাগারগুলি ক্লাসে ব্যক্তিগত সদস্যদের পরীক্ষা করতে প্রতিবিম্বের সম্পত্তি ব্যবহার করে।

অপূর্ণতা:

পারফরম্যান্স ওভারহেড: প্রতিফলনমূলক ক্রিয়াকলাপগুলি তাদের অ-প্রতিবিম্বিত অংশগুলির চেয়ে ধীর পারফরম্যান্স করে এবং কোডের এমন কিছু অংশে এড়ানো উচিত যা কর্মক্ষমতা-সংবেদনশীল অ্যাপ্লিকেশনগুলিতে প্রায়শই বলা হয়।

অভ্যন্তরীণগুলির এক্সপোজার: প্রতিফলিত কোড বিমূর্ততাগুলিকে ভেঙে দেয় এবং তাই প্ল্যাটফর্মের আপগ্রেডের সাথে আচরণ পরিবর্তন করতে পারে।

রেফারেন্স: জাভা প্রতিবিম্ব javarevisited.blogspot.in


4
আমি " এটি রিফ্যাক্টরিং বিরতি " এর ত্রুটিগুলিতে যুক্ত করব । আমার পক্ষে যতটা সম্ভব প্রতিফলন এড়ানোর মূল কারণ।
সান্টিবাইলার্স

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

15

আমার বোঝাপড়া অনুসারে:

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

এটি প্রায়শই এমন পরিস্থিতিতে ব্যবহৃত হয় যেখানে শ্রেণীর নাম ঘন ঘন পরিবর্তিত হয়। যদি এ জাতীয় পরিস্থিতি দেখা দেয় তবে প্রোগ্রামারটির জন্য অ্যাপ্লিকেশনটি পুনরায় লেখা এবং ক্লাসের নাম বারবার পরিবর্তন করা জটিল complicated

পরিবর্তে, প্রতিবিম্ব ব্যবহার করে, সম্ভবত পরিবর্তনশীল শ্রেণীর নাম সম্পর্কে চিন্তা করা দরকার।


15

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

এটি কার্যকর কারণ এটি আপনাকে আপনার প্রোগ্রামের মেটা তথ্যের উপর নির্ভর করে রানটাইম আচরণটি পরিবর্তন করতে দেয়, অর্থাৎ আপনি কোনও ফাংশনের রিটার্ন টাইপ পরীক্ষা করতে পারেন এবং পরিস্থিতি সামাল দেওয়ার উপায়টি পরিবর্তন করতে পারবেন।

সি # তে উদাহরণ হিসাবে আপনি রানটাইমের সময় কোনও অ্যাসেমব্লিকে (a। Dll) এটি পরীক্ষা করে পরীক্ষা করতে পারেন, ক্লাসে ন্যাভিগেট করতে এবং যা খুঁজে পেয়েছেন সে অনুযায়ী পদক্ষেপ নিতে পারেন। এটি আপনাকে রানটাইমে কোনও ক্লাসের উদাহরণ তৈরি করতে, এর পদ্ধতিটি চালিয়ে যাওয়া, ইত্যাদি করতে দেয়

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


11

আমি তালিকাভুক্ত সমস্ত কিছুতে কিছু যুক্ত করতে চাই।

সঙ্গে প্রতিফলন এপিআই আপনি সার্বজনীন লিখতে পারেন toString()কোনো বস্তুর জন্য পদ্ধতি।

এটি ডিবাগিংয়ে দরকারী।

এখানে কিছু উদাহরণ:

class ObjectAnalyzer {

   private ArrayList<Object> visited = new ArrayList<Object>();

   /**
    * Converts an object to a string representation that lists all fields.
    * @param obj an object
    * @return a string with the object's class name and all field names and
    * values
    */
   public String toString(Object obj) {
      if (obj == null) return "null";
      if (visited.contains(obj)) return "...";
      visited.add(obj);
      Class cl = obj.getClass();
      if (cl == String.class) return (String) obj;
      if (cl.isArray()) {
         String r = cl.getComponentType() + "[]{";
         for (int i = 0; i < Array.getLength(obj); i++) {
            if (i > 0) r += ",";
            Object val = Array.get(obj, i);
            if (cl.getComponentType().isPrimitive()) r += val;
            else r += toString(val);
         }
         return r + "}";
      }

      String r = cl.getName();
      // inspect the fields of this class and all superclasses
      do {
         r += "[";
         Field[] fields = cl.getDeclaredFields();
         AccessibleObject.setAccessible(fields, true);
         // get the names and values of all fields
         for (Field f : fields) {
            if (!Modifier.isStatic(f.getModifiers())) {
               if (!r.endsWith("[")) r += ",";
               r += f.getName() + "=";
               try {
                  Class t = f.getType();
                  Object val = f.get(obj);
                  if (t.isPrimitive()) r += val;
                  else r += toString(val);
               } catch (Exception e) {
                  e.printStackTrace();
               }
            }
         }
         r += "]";
         cl = cl.getSuperclass();
      } while (cl != null);

      return r;
   }    
}

11

প্রতিবিম্ব হ'ল তাদের চেহারা দেখতে আপত্তি করা। এই যুক্তি প্রতিবিম্বের সাথে কিছু করার নেই বলে মনে হচ্ছে। আসলে, এটি "স্ব-সনাক্তকরণ" ক্ষমতা।

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


টাইপ (), isinstance (), কলযোগ্য (), dir () এবং getattr ()। .... এগুলি
পাইথোনিক

9

জাভা ডকুমেন্টেশন পৃষ্ঠা থেকে

java.lang.reflectপ্যাকেজ ক্লাস এবং অবজেক্ট সম্পর্কে প্রতিবিম্বিত তথ্য পাওয়ার জন্য ক্লাস এবং ইন্টারফেস সরবরাহ করে। প্রতিবিম্ব ক্ষেত্রগুলি, বোঝা ক্লাসগুলির পদ্ধতি এবং নির্মাতা এবং প্রতিবিম্বিত ক্ষেত্র, পদ্ধতি এবং নির্মাতাদের তাদের সুরক্ষা বিধিনিষেধের মধ্যে অন্তর্নিহিত অংশগুলিতে পরিচালনা করার জন্য তথ্য সম্পর্কিত প্রোগ্রামে অ্যাক্সেসের অনুমতি দেয়।

AccessibleObjectপ্রয়োজনীয় ReflectPermissionউপলব্ধ হলে অ্যাক্সেস চেকগুলিকে দমন করার অনুমতি দেয় ।

এই প্যাকেজের ক্লাসগুলি, java.lang.Classযেমন ডিবাগার, দোভাষী, অবজেক্ট ইন্সপেক্টর, ক্লাস ব্রাউজার এবং পরিষেবাগুলির মতো উপযুক্ত অ্যাপ্লিকেশন সহ Object Serializationএবং JavaBeansযে কোনও টার্গেটের অবজেক্টের (তার রানটাইম শ্রেণির উপর ভিত্তি করে) পাবলিক সদস্যদের বা তার দ্বারা ঘোষিত সদস্যদের অ্যাক্সেসের প্রয়োজন রয়েছে একটি প্রদত্ত বর্গ

এটিতে নিম্নলিখিত কার্যকারিতা অন্তর্ভুক্ত রয়েছে।

  1. শ্রেণীর অবজেক্ট প্রাপ্তি,
  2. শ্রেণীর বৈশিষ্ট্যগুলি পরীক্ষা করা (ক্ষেত্র, পদ্ধতি, নির্মাণকারী),
  3. ক্ষেত্রের মান নির্ধারণ এবং প্রাপ্ত করা,
  4. আমন্ত্রণ পদ্ধতি,
  5. বস্তুর নতুন দৃষ্টান্ত তৈরি করা।

শ্রেণীর দ্বারা উন্মুক্ত পদ্ধতিগুলির জন্য এই ডকুমেন্টেশন লিঙ্কটি একবার দেখুন Class

এই নিবন্ধটি থেকে (ডেনিস সোসনোস্কি, রাষ্ট্রপতি, সোসনোস্কি সফটওয়্যার সলিউশনস, ইনক) এবং এই নিবন্ধটি (সুরক্ষা-অনুসন্ধান পিডিএফ):

প্রতিবিম্ব ব্যবহারের তুলনায় আমি যথেষ্ট ত্রুটি দেখতে পাচ্ছি

প্রতিবিম্বের ব্যবহারকারী:

  1. এটি প্রোগ্রামের উপাদানগুলিকে গতিশীলভাবে সংযুক্ত করার জন্য বহুমুখী উপায় সরবরাহ করে
  2. এটি খুব সাধারণ উপায়ে অবজেক্টগুলির সাথে কাজ করে এমন লাইব্রেরি তৈরির জন্য দরকারী

প্রতিবিম্বের ত্রুটিগুলি:

  1. ক্ষেত্র এবং পদ্ধতি অ্যাক্সেসের জন্য ব্যবহৃত হলে সরাসরি কোডের চেয়ে প্রতিবিম্ব অনেক ধীর হয়।
  2. এটি আপনার কোডের অভ্যন্তরে কী ঘটছে তা অস্পষ্ট করতে পারে
  3. এটি উত্স কোডকে বাইপাস করে রক্ষণাবেক্ষণের সমস্যা তৈরি করতে পারে
  4. প্রতিবিম্ব কোডটিও সম্পর্কিত সরাসরি কোডের চেয়ে জটিল
  5. এটি ডেটা অ্যাক্সেস সুরক্ষা এবং সুরক্ষা প্রকারের মতো কী জাভা সুরক্ষা সীমাবদ্ধতার লঙ্ঘনের অনুমতি দেয়

সাধারণ আপত্তি:

  1. সীমাবদ্ধ ক্লাসগুলি লোড করা,
  2. একটি সীমাবদ্ধ শ্রেণীর কনস্ট্রাক্টর, পদ্ধতি বা ক্ষেত্রের বিষয়ে রেফারেন্স পাওয়া,
  3. নতুন অবজেক্টের দৃষ্টান্ত তৈরি করা, পদ্ধতিগুলির অনুরোধ করা, একটি সীমাবদ্ধ শ্রেণীর ক্ষেত্রের মানগুলি নির্ধারণ করা বা সেট করা।

প্রতিবিম্ব বৈশিষ্ট্যটির অপব্যবহার সম্পর্কিত এই এসই প্রশ্নটি দেখুন:

আমি জাভাতে কোনও ব্যক্তিগত ক্ষেত্র কীভাবে পড়ব?

সারসংক্ষেপ:

সিস্টেম কোডের মধ্যে থেকে এর ক্রিয়াকলাপগুলির অনিরাপদ ব্যবহার সহজেই জাভা সুরক্ষা মোডের সমঝোতার কারণ হতে পারে l তাই এই বৈশিষ্ট্যটি অল্প পরিমাণে ব্যবহার করুন


কিছু ক্ষেত্রে প্রতিবিম্বের কার্যক্ষমতা সমস্যাগুলি এড়ানোর একটি উপায় হ'ল কোন ক্লাসটি Woozleস্ট্যাটিক RegisterAsWoozleHelper()পদ্ধতিতে রয়েছে তা দেখার জন্য ক্লাসটি অন্য ক্লাসগুলি পরীক্ষা করে দেখানো হয় এবং এই জাতীয় সমস্ত পদ্ধতিগুলি কলব্যাকের সাহায্যে অনুরোধ করে যা তারা Woozleনিজের সম্পর্কে বলার জন্য ব্যবহার করতে পারে যেমন ডেটা ডিজাইরিজ করার সময় প্রতিবিম্ব ব্যবহার করা দরকার।
সুপারক্যাট

9

নাম হিসাবে নিজেই ইঙ্গিত দেয় যে এটি উদাহরণস্বরূপ শ্রেণি পদ্ধতি ইত্যাদির জন্য এটি কী ধারণ করে তা প্রতিফলিত করে রানটাইম সময়ে গতিশীল পদ্ধতিতে পদ্ধতি তৈরির জন্য বৈশিষ্ট্য সরবরাহ করা ছাড়াও।

এটি কাঠামোর নীচে অনেকগুলি ফ্রেমওয়ার্ক এবং অ্যাপ্লিকেশন দ্বারা কোডটি প্রকৃতপক্ষে না জেনে পরিষেবাদি শুরু করতে ব্যবহৃত হয়।


7

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


6

Reflectionঅনেক ব্যবহার আছে । যার সাথে আমি বেশি পরিচিত, তিনি হ'ল ফ্লাইতে কোড তৈরি করতে সক্ষম হন।

আইই: গতিশীল ক্লাস, ফাংশন, কনস্ট্রাক্টর - যে কোনও ডেটা (এক্সএমএল / অ্যারে / এসকিএল ফলাফল / হার্ডকোডেড ইত্যাদি) এর উপর ভিত্তি করে)


1
আপনি যদি এসকিউএল ফলাফল বা এক্সএমএল ফাইল ইত্যাদি থেকে উত্পন্ন কোডের একটি মাত্র অস্বাভাবিক উদাহরণ দেন তবে এই উত্তরটি আরও অনেক ভাল হবে
ক্লার্ক

সমস্যা নেই. আমি একটি উইন্ডোজ অ্যাপ্লিকেশনটিতে প্রতিচ্ছবি ব্যবহার করেছি যা একটি ডাটাবেস থেকে নেওয়া এক্সএমএল এর উপর ভিত্তি করে গতিযুক্ত ইন্টারফেস উত্পন্ন করে।
এসএস কে

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

3

আমি উদাহরণ দিয়ে এই প্রশ্নের উত্তর দিতে চাই। সর্বপ্রথম Hibernateপ্রকল্পটি চলমান অ্যাপ্লিকেশন এবং অধ্যবসায় স্টোরের মধ্যে কুশল ব্রিজ করতে বিবৃতি Reflection APIউত্পন্ন করতে ব্যবহার করে CRUD। জিনিসগুলি যখন ডোমেনে পরিবর্তিত হয়, Hibernateতখন ডেটা স্টোর এবং তার বিপরীতে এগুলি চালিয়ে যাওয়ার জন্য তাদের সম্পর্কে তাদের জানতে হবে।

বিকল্পভাবে কাজ করে Lombok Project। এটি কেবল সংকলনের সময় কোডটিকে ইনজেকশন দেয়, ফলস্বরূপ কোডটি আপনার ডোমেন ক্লাসগুলিতে sertedোকানো হয়। (আমি মনে করি এটি গ্রাহকদের এবং সেটটারদের জন্য ঠিক আছে)

Hibernateচয়ন করা হয়েছে reflectionকারণ এটি কোনও অ্যাপ্লিকেশনের জন্য বিল্ড প্রক্রিয়াতে ন্যূনতম প্রভাব ফেলে।

এবং জাভা 7 থেকে আমাদের রয়েছে MethodHandles, যা কাজ করে Reflection API। প্রকল্পগুলিতে, লগারদের সাথে কাজ করার জন্য আমরা কেবলমাত্র পরবর্তী কোডটি অনুলিপি করতে পারি:

Logger LOGGER = Logger.getLogger(MethodHandles.lookup().lookupClass().getName());

কারণ এক্ষেত্রে টাইপ-ত্রুটি করা শক্ত।


3

যেহেতু আমি উদাহরণ দিয়ে ব্যাখ্যা করা ভাল বলে মনে হয় এবং উত্তরগুলির কোনওটিই এটি করে বলে মনে হয় না ...

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

একটি পৃথক উদাহরণ একটি ব্যক্তিগত পদ্ধতির ইউনিট-পরীক্ষা হবে। এটি করার একটি উপায় হ'ল প্রতিচ্ছবি তৈরি করা এবং পরীক্ষার সেট আপ পর্যায়ে পদ্ধতির ক্ষেত্রটি জনসাধারণের কাছে পরিবর্তন করা। অবশ্যই কেউ যুক্তি দিতে পারেন যে ব্যক্তিগত পদ্ধতিগুলি সরাসরি পরীক্ষা করা উচিত নয় তবে এটি মুল বিষয় নয়।

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