"Class.forName ()" এবং "Class.forName ()। NewInstance ()" এর মধ্যে পার্থক্য কী?


165

মধ্যে পার্থক্য কি Class.forName()এবং Class.forName().newInstance()?

আমি তাৎপর্যপূর্ণ পার্থক্য বুঝতে পারি না (আমি তাদের সম্পর্কে কিছু পড়েছি!)। দয়া করে আমাকে একটু সাহায্য করবেন?

উত্তর:


247

উভয় পদ্ধতি কীভাবে ব্যবহৃত হয় তা প্রমাণ করে এমন একটি উদাহরণ আপনাকে জিনিসগুলি আরও ভালভাবে বুঝতে সহায়তা করবে। সুতরাং, নিম্নলিখিত শ্রেণীর বিবেচনা করুন:

package test;

public class Demo {

    public Demo() {
        System.out.println("Hi!");
    }

    public static void main(String[] args) throws Exception {
        Class clazz = Class.forName("test.Demo");
        Demo demo = (Demo) clazz.newInstance();
    }
}

হিসাবে তার javadoc ব্যাখ্যা, কলিং রিটার্ন বর্গ বা প্রদত্ত স্ট্রিং নাম দিয়ে ইন্টারফেসের সাথে যুক্ত বস্তু অর্থাৎ আয় যা প্রভাবিত হয় ধরনের পরিবর্তনশীল ।Class.forName(String) Classtest.Demo.classclazzClass

তারপরে, কলিং এই বস্তুর দ্বারা প্রতিনিধিত্ব করা শ্রেণীর একটি নতুন উদাহরণ তৈরি করে ক্লাসটি তাত্ক্ষণিকভাবে শূন্য যুক্তি তালিকার একটি অভিব্যক্তি দ্বারা অন্য কথায়, এটি এখানে আসলে একটি এর সমতুল্য এবং এর একটি নতুন উদাহরণ প্রদান করে ।clazz.newInstance() Classnewnew Demo()Demo

এবং এই Demoক্লাসটি চালানো নীচের আউটপুট প্রিন্ট করে:

Hi!

Traditionalতিহ্যগত সাথে বড় পার্থক্য newহ'ল এমন newInstanceকোনও শ্রেণিকে ইনস্ট্যান্ট করতে দেয় যা আপনি রানটাইম অবধি জানেন না, আপনার কোডটিকে আরও গতিশীল করে তোলে।

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

আসলে, আপনি আরও যেতে চাইলে টেড নিউয়ার্ড পেপার বোঝার ক্লাস.ফরনেম () দেখুন যে আমি ঠিক উপরের অনুচ্ছেদে প্যারাফ্রেস করছি।

সম্পাদনা (মন্তব্য হিসাবে পোস্ট করা ওপির একটি প্রশ্নের জবাব): জেডিবিসি চালকদের ক্ষেত্রে কিছুটা বিশেষ। জেডিবিসি এপিআই দিয়ে যাত্রা শুরু করার ড্রাইভার ম্যানেজার অধ্যায়ে যেমন ব্যাখ্যা করা হয়েছে :

(...) একটি Driverশ্রেণি লোড করা হয়, এবং সেইজন্য স্বয়ংক্রিয়ভাবে DriverManagerদুটি পদ্ধতির মধ্যে একটিতে নিবন্ধিত হয় :

  1. পদ্ধতি কল করে Class.forName। এটি স্পষ্টভাবে ড্রাইভার ক্লাসটি লোড করে। যেহেতু এটি কোনও বাহ্যিক সেটআপের উপর নির্ভর করে না, DriverManager ফ্রেমওয়ার্কটি ব্যবহারের জন্য ড্রাইভার লোড করার এই উপায়টিই প্রস্তাবিত । নিম্নলিখিত কোডটি ক্লাসে লোড করে acme.db.Driver:

    Class.forName("acme.db.Driver");

    যদি acme.db.Driverএটি এমনভাবে লেখা থাকে যাতে এটি লোড হওয়ার ফলে একটি উদাহরণ তৈরি হয় এবং DriverManager.registerDriverসেই উদাহরণটি পরামিতি হিসাবে কল করা হয় (এটি যেমন করা উচিত) তবে এটি DriverManagerড্রাইভারের তালিকায় রয়েছে এবং সংযোগ তৈরির জন্য উপলব্ধ available

  2. (...)

এই উভয় ক্ষেত্রেই, সদ্য-বোঝা Driverশ্রেণীর কাছে ফোন করে নিজেকে নিবন্ধন করা দায়বদ্ধ DriverManager.registerDriver। উল্লিখিত হিসাবে, ক্লাসটি লোড হওয়ার পরে এটি স্বয়ংক্রিয়ভাবে করা উচিত।

আরম্ভের সময় নিজেদের নিবন্ধন করতে, জেডিবিসি ড্রাইভার সাধারণত স্ট্যাটিক ইনিশিয়ালাইজেশন ব্লক ব্যবহার করে:

package acme.db;

public class Driver {

    static {
        java.sql.DriverManager.registerDriver(new Driver());
    }

    ...
}

কলিং ক্লাসের Class.forName("acme.db.Driver")আরম্ভের কারণ acme.db.Driverএবং এইভাবে স্থিতিশীল আরম্ভের ব্লক কার্যকর করে। এবং Class.forName("acme.db.Driver")প্রকৃতপক্ষে একটি উদাহরণ "তৈরি" করবে তবে এটি কীভাবে (ভাল) জেডিবিসি ড্রাইভার বাস্তবায়িত হবে তার একটি পরিণতি।

পার্শ্ব নোট হিসাবে, আমি উল্লেখ করব যে জেডিবিসি ৪.০ (জাভা since-এর পরে একটি ডিফল্ট প্যাকেজ হিসাবে যুক্ত) এবং জেডিবিসি drivers.০ ড্রাইভারের নতুন অটো-লোডিং বৈশিষ্ট্যের সাথে এই সমস্ত কিছুর প্রয়োজন নেই। জাভা এসই 6 তে জেডিবিসি 4.0 বর্ধন দেখুন ।



2
উপরের সাইটে লেখা আছে: "Class.forName কল করা স্বয়ংক্রিয়ভাবে একটি ড্রাইভারের একটি উদাহরণ তৈরি করে এবং এটি ড্রাইভার ম্যানেজারের সাথে নিবন্ধভুক্ত করে, তাই আপনাকে ক্লাসের কোনও উদাহরণ তৈরি করার দরকার নেই। আপনি যদি নিজের ইন্সটিশন তৈরি করে থাকেন তবে , আপনি একটি অপ্রয়োজনীয় সদৃশ তৈরি করবেন, তবে এতে কোনও ক্ষতি হবে না। " এর অর্থ হ'ল Class.forName দ্বারা আপনি বাহ্যিকভাবে একটি উদাহরণ তৈরি করবেন এবং যদি আপনি অন্যটি তৈরি করতে চান তবে এটি একটি অপ্রয়োজনীয় উদাহরণ তৈরি করবে সুতরাং Calss.forName () এবং Class.forName () উভয়ই নতুন ইনসট্যান্স () উদাহরণ তৈরি করবে চালক !!
জোহানা

10
জেডিবিসি ড্রাইভারগুলি "বিশেষ", এগুলি একটি স্ট্যাটিক ইনিশিয়ালাইজেশন ব্লক দিয়ে লেখা হয় যেখানে একটি উদাহরণ তৈরি করা হয় এবং এর পরামিতি হিসাবে পাস করা হয় DriverManager.registerDriverClass.forNameজেডিবিসি ড্রাইভারকে কল করার ফলে এটির সূচনা হয় এবং এভাবে স্থিতিশীল ব্লক কার্যকর হয়। উদাহরণস্বরূপ java2s.com / ওপেন-সোর্স / জাভা- ডকুমেন্ট / ডেটাবেস-DBMS/… দেখুন । সুতরাং ড্রাইভার ইন্টার্নালগুলির কারণে এটি আসলে একটি বিশেষ ক্ষেত্রে।
পাস্কাল থিভেন্ট

1
আমি লক্ষ করেছি যে অন্য উত্তরে , Class.newInstance () ব্যবহার করে দৃ strongly়ভাবে নিরুৎসাহিত করা হয়েছে। ক্লাস.জেট কনস্ট্রাক্টর () এর পরে কনস্ট্রাক্টর.নেইউইনস্ট্যান্স () পরিবর্তে ব্যবহার করার পরামর্শ দেওয়া হচ্ছে। এটি সম্ভাব্য ব্যতিক্রম মুখোশ এড়ানো এড়ায়।
এলএস

"newInstance এমন একটি ক্লাস ইনস্ট্যান্ট করতে দেয় যা আপনি রানটাইম অবধি জানেন না" আমার দিনটি তৈরি করে। ধন্যবাদ।
কোড উত্সাহী

37

Class.forName () আপনাকে ক্লাস অবজেক্ট দেয় যা প্রতিবিম্বের জন্য কার্যকর। এই বস্তুটি যে পদ্ধতিগুলি করেছে তা জাভা দ্বারা সংজ্ঞায়িত করা হয়েছে, ক্লাস লেখার দ্বারা প্রোগ্রামার দ্বারা নয়। তারা প্রতিটি শ্রেণীর জন্য একই। এর উপর NewInstance () কল করা আপনাকে সেই শ্রেণীর উদাহরণ দেয় (অর্থাত Class.forName("ExampleClass").newInstance()এটি কল করার সমতুল্য new ExampleClass()), যার উপর আপনি ক্লাসটি যে পদ্ধতিগুলি নির্ধারণ করে, দৃশ্যমান ক্ষেত্রগুলি অ্যাক্সেস করতে পারেন ইত্যাদি কল করতে পারেন etc.


29

জেডিবিসি বিশ্বে, সাধারণ অনুশীলন (জেডিবিসি এপিআই অনুযায়ী) আপনি Class#forName()জেডিবিসি ড্রাইভার লোড করতে ব্যবহার করেন। জেডিবিসি ড্রাইভারকে অবশ্যই DriverManagerএকটি স্ট্যাটিক ব্লকের ভিতরে নিবন্ধন করা উচিত :

package com.dbvendor.jdbc;

import java.sql.Driver;
import java.sql.DriverManager;

public class MyDriver implements Driver {

    static {
        DriverManager.registerDriver(new MyDriver());
    }

    public MyDriver() {
        //
    }

}

আমন্ত্রণ Class#forName()সমস্ত স্থিতিশীল আরম্ভকারী কার্যকর করা হবে । এইভাবে DriverManagerসংযোগ ইউআরএল দ্বারা নিবন্ধিত ড্রাইভারদের মধ্যে সম্পর্কিত ড্রাইভারটি খুঁজে পেতে পারেন getConnection()যা মোটামুটি নীচের মত দেখাচ্ছে:

public static Connection getConnection(String url) throws SQLException {
    for (Driver driver : registeredDrivers) {
        if (driver.acceptsURL(url)) {
            return driver.connect(url);
        }
    }
    throw new SQLException("No suitable driver");
}

তবে বগি জেডিবিসি ড্রাইভারগুলিও ছিল, org.gjt.mm.mysql.Driverযেমনটি সুপরিচিত উদাহরণ দিয়ে শুরু হয়েছিল , যা স্থির ব্লকের পরিবর্তে ভুলভাবে কন্সট্রাক্টরের ভিতরে নিজেকে নিবন্ধিত করে :

package com.dbvendor.jdbc;

import java.sql.Driver;
import java.sql.DriverManager;

public class BadDriver implements Driver {

    public BadDriver() {
        DriverManager.registerDriver(this);
    }

}

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


17

1: আপনি যদি কেবলমাত্র ক্লাসের স্ট্যাটিক ব্লকটিতে আগ্রহী হন, ক্লাসের লোড করা কেবলমাত্র তাই করবে, এবং স্ট্যাটিক ব্লকগুলি কার্যকর করবে তবে আপনার যা প্রয়োজন তা হ'ল:

Class.forName("Somthing");

2: আপনি যদি ক্লাসটি লোড করতে আগ্রহী হন, এর স্ট্যাটিক ব্লকগুলি কার্যকর করুন এবং এর অ স্থিত অংশটি অ্যাক্সেস করতে চান, তবে আপনার একটি উদাহরণ প্রয়োজন এবং তারপরে আপনার প্রয়োজন:

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

দুর্দান্ত উত্তর! স্পষ্ট এবং সংক্ষিপ্ত!
গৌরব

6

Class.forName () ক্লাসের জন্য একটি রেফারেন্স পেয়ে যায়, Class.forName ()। NewInstance () ক্লাসের জন্য নো-আরগ কনস্ট্রাক্টরকে একটি নতুন উদাহরণ ফেরত দেওয়ার চেষ্টা করে।


3

"Class.forName ()" প্রদত্ত নামের জন্য শ্রেণি-প্রকারটি প্রদান করে। "newInstance ()" এই শ্রেণীর উদাহরণ দেয়।

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

"Class.forName ()" এর উদাহরণ

Class myClass = Class.forName("test.MyClass");
System.out.println("Number of public methods: " + myClass.getMethods().length);

"Class.forName ()। NewInstance ()" এর উদাহরণ

MyClass myClass = (MyClass) Class.forName("test.MyClass").newInstance();
System.out.println("String representation of MyClass instance: " + myClass.toString());

3

কেবলমাত্র উপরের উত্তরের সাথে যুক্ত করা, যখন আমাদের কাছে একটি স্ট্যাটিক কোড থাকে (যেমন কোড ব্লক উদাহরণ স্বতন্ত্র) যা মেমরিতে উপস্থিত থাকতে হবে, আমরা ক্লাসটি ফিরিয়ে আনতে পারি তাই আমরা Class.forname ("কিছু নাম") ব্যবহার করব অন্যথায় যদি আমরা স্ট্যাটিক কোড নেই যা আমরা Class.forname ()। newInstance ("someName") এর জন্য যেতে পারি কারণ এটি মেমরিটিতে অবজেক্ট লেভেল কোড ব্লকগুলি (অ স্থিতিশীল) লোড করবে as


1

আপনি ক্লাস.ফরনাম () পদ্ধতিটি কতবার কল করেন তা নয়, কেবল একবার স্ট্যাটিক ব্লক একাধিকবার কার্যকর করা হয় না:

নেমমেথডেমো জন্য প্যাকেজ;

পাবলিক ক্লাস মেইনক্লাস {

    public static void main(String[] args) throws Exception {
        Class.forName("forNameMethodDemo.DemoClass");
        Class.forName("forNameMethodDemo.DemoClass");
        Class.forName("forNameMethodDemo.DemoClass");
        DemoClass demoClass = (DemoClass)Class.forName("forNameMethodDemo.DemoClass").newInstance();
    }

}

পাবলিক ক্লাস ডেমোক্লাস {

static {
    System.out.println("in Static block");
}

{
    System.out.println("in Instance block");
}

}

আউটপুট হবে:

in Static block in Instance block

এই in Static blockবিবৃতিটি তিনবার নয় একবারই মুদ্রিত হয়েছে।


0

Class.forName () -> forName () ক্লাস শ্রেণীর স্থির পদ্ধতি এটি প্রতিচ্ছবি হিসাবে ব্যবহৃত শ্রেণীর শ্রেণীর অবজেক্ট ব্যবহারকারী শ্রেণীর অবজেক্টকে দেয় না তাই আপনি কেবল এটিতে ক্লাস ক্লাস পদ্ধতিগুলি কল করতে পারেন যেমন getMethods (), getConstructors () ইত্যাদি etc.

আপনি যদি আপনার (রানটাইম প্রদত্ত) শ্রেণীর কেবল স্ট্যাটিক ব্লকটি চালানোর বিষয়ে চিন্তা করেন এবং কেবল আপনার ক্লাসের পদ্ধতি, নির্মাতা, সংশোধক ইত্যাদির তথ্য পান তবে আপনি ক্লাস.ফোর্নাম () ব্যবহার করে এই অবজেক্টটি দিয়ে করতে পারেন)

তবে আপনি যদি নিজের ক্লাস পদ্ধতিটি অ্যাক্সেস করতে বা কল করতে চান (রানটাইমের সময় আপনি যে ক্লাসটি দিয়েছিলেন) তবে আপনার অবজেক্টটি এত তাড়াতাড়ি করা দরকার ক্লাস ক্লাসের নতুন পদ্ধতি পদ্ধতিটি আপনার জন্য করা উচিত t এটি ক্লাসের নতুন উদাহরণ তৈরি করে আপনাকে তা ফেরত দেবে .এটি আপনার ক্লাসে টাইপ-কাস্ট করা দরকার।

উদাহরণস্বরূপ: ধরুন কর্মচারী তখন আপনার ক্লাস

শ্রেণি a = Class.forName (আরগস [0]);

// আরগস [0] = রানটাইমের সময় শ্রেণি দেওয়ার জন্য লিমিটেড লাইন সেমি।

কর্মচারী ob1 = a.newInstance ();

a.newInstance () নতুন কর্মচারী () ব্যবহার করে অবজেক্ট তৈরি করার অনুরূপ।

এখন আপনি আপনার সমস্ত শ্রেণীর দৃশ্যমান ক্ষেত্র এবং পদ্ধতিগুলি অ্যাক্সেস করতে পারেন।

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