জাভাতে নাম দিয়ে কোনও শ্রেণি ইনস্ট্যান্ট করার কোনও উপায় আছে কি?


102

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


আমরা একটি ক্লাস ইনস্ট্যান্ট করি এবং ফলাফলটি একটি অবজেক্ট (বা: উদাহরণ )।
আন্ড্রেয়াস ডলক

1
উত্তর হ্যাঁ, তবে আমি মনে করি আপনার এটি জিজ্ঞাসা করা উচিত এটি ভাল ধারণা কিনা । দুর্দান্ত শক্তির (প্রতিবিম্ব) সাথে দুর্দান্ত দায়িত্ব আসে এবং আপনি যদি তা বুঝতে এবং ফলাফলগুলি বিবেচনা করে থাকেন তবে আপনার কেবল এটি ব্যবহার করা উচিত।
c1moore

উত্তর:


238

দুইটি রাস্তা:

পদ্ধতি 1 - কেবল কোনও ক্লাবের জন্য যেখানে কোনও নো-আরগ কনস্ট্রাক্টর রয়েছে

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

উদাহরণ স্বরূপ:

Class<?> clazz = Class.forName("java.util.Date");
Object date = clazz.newInstance();

পদ্ধতি 2

ক্লাসে কোনও নো-আরগ কনস্ট্রাক্টর না থাকলে একটি বিকল্প নিরাপদ পদ্ধতি যা কাজ করে তা হ'ল আপনার ক্লাস অবজেক্টটি তার Constructorঅবজেক্টটি পেতে এটি জিজ্ঞাসা করা এবং newInstance()এই বস্তুটিতে একটি পদ্ধতি কল করতে :

Class<?> clazz = Class.forName("com.foo.MyClass");
Constructor<?> constructor = clazz.getConstructor(String.class, Integer.class);
Object instance = constructor.newInstance("stringparam", 42);

উভয় পদ্ধতিই প্রতিবিম্ব হিসাবে পরিচিত । আপনাকে সাধারণত বিভিন্ন ব্যতিক্রম হতে পারে যা ঘটতে পারে, যেমন:

  • জেভিএম খুঁজে পাচ্ছে না বা আপনার ক্লাসটি লোড করতে পারে না
  • আপনি যে ক্লাসটি ইনস্ট্যান্ট করার চেষ্টা করছেন তার সঠিক নির্মাতারা নেই
  • নির্মাতা নিজেই একটি ব্যতিক্রম ছুঁড়ে ফেলেছে
  • আপনি যে নির্মাতাকে অনুরোধ করার চেষ্টা করছেন তা সর্বজনীন নয়
  • একটি সুরক্ষা পরিচালক ইনস্টল করা হয়েছে এবং প্রতিবিম্ব ঘটতে বাধা দিচ্ছে

হাই, আমরা একবার থেকে বস্তুটি তৈরি করার পরে newInstance(), আমরা কি এটি আবার আমাদের নিজস্ব বস্তুটিতে ফেলে দিতে পারি?
GMsoF

@ সিমন আপনি কি সুরক্ষা পরিচালক সম্পর্কে বিস্তারিত / বর্ণনা দিতে পারেন?
রাম

আমি এটা বুঝতে পারি না। আমি অন্য কোনও ডিরেক্টরিতে অজানা ফাইলের একটি শ্রেণিতে অ্যাক্সেস করতে চাই, আমার কাছে কেবল স্ট্রিং হিসাবে পথ / ফাইলের নাম রয়েছে। স্ট্রিং "dir / unkonwn.java"। Class.forName ("dir / অজানা") কল করা আমাকে ত্রুটি দেয়।
জন কেটজিক

কীভাবে আমরা কাস্ট করতে পারেন instanceকরতে com.foo.MyClass? প্রদত্ত যে com.foo.MyClass কেবল একটি স্ট্রিং
Sanket9394

14
MyClass myInstance = (MyClass) Class.forName("MyClass").newInstance();

15
এটি উল্লেখ করার মতো যে ক্লাসে কোনও প্যারামিটারলেস কনস্ট্রাক্টর না থাকলে (এবং অন্যান্য নির্মাণকারী রয়েছে), বা প্যারামিটারলেস কনস্ট্রাক্টর যদি অ্যাক্সেসযোগ্য হয় তবে এটি কাজ করে না।
দাউদ ইবনে কেরেম

3

Class.forName ("শ্রেণীর স্ট্রিং নাম") ব্যবহার করুন new newInstance ();

Class.forName("A").newInstance();

এটি এ আঞ্চলিকৃত নামের শ্রেণীর কারণ ঘটবে।


এমনকি প্যাকেজের নাম প্রিপেন্ড করেও আমার পক্ষে কাজ করে না। :(
trusktr

3

কোনও ক্লাসের সম্পূর্ণরূপে যোগ্য নামটি ব্যবহার করে উদাহরণটি তৈরি করতে আরও সহজ করার জন্য Class.forName(...), কেউ এই Class.getName()পদ্ধতিটি ব্যবহার করতে পারেন । কিছুটা এইরকম:

class ObjectMaker {
    // Constructor, fields, initialization, etc...
    public Object makeObject(Class<?> clazz) {
        Object o = null;

        try {
            o = Class.forName(clazz.getName()).newInstance();
        } catch (ClassNotFoundException e) {
            // There may be other exceptions to throw here, 
            // but I'm writing this from memory.
            e.printStackTrace();
        }

        return o;
    }
}

তারপরে আপনি যে ক্লাসে পাস করবেন সেটিকে আপনি ফিরে পেতে পারেন makeObject(...):

Data d = (Data) objectMaker.makeObject(Data.class);

1
আপনি কি কেবল তখনকার clazz.newInstance()পরিবর্তে পারবেন না ? getNamefromName
ব্যবহারকারী 276648

1

জাভা প্রতিবিম্ব ব্যবহার করুন

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

import java.lang.reflect.*;

   public class constructor2 {
      public constructor2()
      {
      }

      public constructor2(int a, int b)
      {
         System.out.println(
           "a = " + a + " b = " + b);
      }

      public static void main(String args[])
      {
         try {
           Class cls = Class.forName("constructor2");
           Class partypes[] = new Class[2];
            partypes[0] = Integer.TYPE;
            partypes[1] = Integer.TYPE;
            Constructor ct 
              = cls.getConstructor(partypes);
            Object arglist[] = new Object[2];
            arglist[0] = new Integer(37);
            arglist[1] = new Integer(47);
            Object retobj = ct.newInstance(arglist);
         }
         catch (Throwable e) {
            System.err.println(e);
         }
      }
   }

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





0

newInstance()জাভা 8 হিসাবে সরাসরি ব্যবহার অবচিত করা হয়েছে You Class.getDeclaredConstructor(...).newInstance(...)আপনার সংশ্লিষ্ট ব্যতিক্রমগুলি ব্যবহার করতে হবে ।

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