উত্তর:
উভয় পদ্ধতি কীভাবে ব্যবহৃত হয় তা প্রমাণ করে এমন একটি উদাহরণ আপনাকে জিনিসগুলি আরও ভালভাবে বুঝতে সহায়তা করবে। সুতরাং, নিম্নলিখিত শ্রেণীর বিবেচনা করুন:
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)
Class
test.Demo.class
clazz
Class
তারপরে, কলিং এই বস্তুর দ্বারা প্রতিনিধিত্ব করা শ্রেণীর একটি নতুন উদাহরণ তৈরি করে । ক্লাসটি তাত্ক্ষণিকভাবে শূন্য যুক্তি তালিকার একটি অভিব্যক্তি দ্বারা । অন্য কথায়, এটি এখানে আসলে একটি এর সমতুল্য এবং এর একটি নতুন উদাহরণ প্রদান করে ।clazz.newInstance()
Class
new
new Demo()
Demo
এবং এই Demo
ক্লাসটি চালানো নীচের আউটপুট প্রিন্ট করে:
Hi!
Traditionalতিহ্যগত সাথে বড় পার্থক্য new
হ'ল এমন newInstance
কোনও শ্রেণিকে ইনস্ট্যান্ট করতে দেয় যা আপনি রানটাইম অবধি জানেন না, আপনার কোডটিকে আরও গতিশীল করে তোলে।
একটি সাধারণ উদাহরণ জেডিবিসি এপিআই যা রানটাইম সময়ে কাজ চালানোর জন্য সঠিক ড্রাইভারের প্রয়োজন হয় load ইজেবি কনটেইনারগুলি, সার্লেট পাত্রে অন্যান্য ভাল উদাহরণ: তারা রানটাইমের আগে কিছু জানেন না এমন উপাদানগুলি লোড করতে এবং তৈরি করতে গতিশীল রানটাইম লোডিং ব্যবহার করে।
আসলে, আপনি আরও যেতে চাইলে টেড নিউয়ার্ড পেপার বোঝার ক্লাস.ফরনেম () দেখুন যে আমি ঠিক উপরের অনুচ্ছেদে প্যারাফ্রেস করছি।
সম্পাদনা (মন্তব্য হিসাবে পোস্ট করা ওপির একটি প্রশ্নের জবাব): জেডিবিসি চালকদের ক্ষেত্রে কিছুটা বিশেষ। জেডিবিসি এপিআই দিয়ে যাত্রা শুরু করার ড্রাইভার ম্যানেজার অধ্যায়ে যেমন ব্যাখ্যা করা হয়েছে :
(...) একটি
Driver
শ্রেণি লোড করা হয়, এবং সেইজন্য স্বয়ংক্রিয়ভাবেDriverManager
দুটি পদ্ধতির মধ্যে একটিতে নিবন্ধিত হয় :
পদ্ধতি কল করে
Class.forName
। এটি স্পষ্টভাবে ড্রাইভার ক্লাসটি লোড করে। যেহেতু এটি কোনও বাহ্যিক সেটআপের উপর নির্ভর করে না,DriverManager
ফ্রেমওয়ার্কটি ব্যবহারের জন্য ড্রাইভার লোড করার এই উপায়টিই প্রস্তাবিত । নিম্নলিখিত কোডটি ক্লাসে লোড করেacme.db.Driver
:Class.forName("acme.db.Driver");
যদি
acme.db.Driver
এটি এমনভাবে লেখা থাকে যাতে এটি লোড হওয়ার ফলে একটি উদাহরণ তৈরি হয় এবংDriverManager.registerDriver
সেই উদাহরণটি পরামিতি হিসাবে কল করা হয় (এটি যেমন করা উচিত) তবে এটিDriverManager
ড্রাইভারের তালিকায় রয়েছে এবং সংযোগ তৈরির জন্য উপলব্ধ available(...)
এই উভয় ক্ষেত্রেই, সদ্য-বোঝা
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 বর্ধন দেখুন ।
DriverManager.registerDriver
। Class.forName
জেডিবিসি ড্রাইভারকে কল করার ফলে এটির সূচনা হয় এবং এভাবে স্থিতিশীল ব্লক কার্যকর হয়। উদাহরণস্বরূপ java2s.com / ওপেন-সোর্স / জাভা- ডকুমেন্ট / ডেটাবেস-DBMS/… দেখুন । সুতরাং ড্রাইভার ইন্টার্নালগুলির কারণে এটি আসলে একটি বিশেষ ক্ষেত্রে।
Class.forName () আপনাকে ক্লাস অবজেক্ট দেয় যা প্রতিবিম্বের জন্য কার্যকর। এই বস্তুটি যে পদ্ধতিগুলি করেছে তা জাভা দ্বারা সংজ্ঞায়িত করা হয়েছে, ক্লাস লেখার দ্বারা প্রোগ্রামার দ্বারা নয়। তারা প্রতিটি শ্রেণীর জন্য একই। এর উপর NewInstance () কল করা আপনাকে সেই শ্রেণীর উদাহরণ দেয় (অর্থাত Class.forName("ExampleClass").newInstance()
এটি কল করার সমতুল্য new ExampleClass()
), যার উপর আপনি ক্লাসটি যে পদ্ধতিগুলি নির্ধারণ করে, দৃশ্যমান ক্ষেত্রগুলি অ্যাক্সেস করতে পারেন ইত্যাদি কল করতে পারেন etc.
জেডিবিসি বিশ্বে, সাধারণ অনুশীলন (জেডিবিসি এপিআই অনুযায়ী) আপনি 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()
দূরে ছেড়ে যেতে পারেন।
1: আপনি যদি কেবলমাত্র ক্লাসের স্ট্যাটিক ব্লকটিতে আগ্রহী হন, ক্লাসের লোড করা কেবলমাত্র তাই করবে, এবং স্ট্যাটিক ব্লকগুলি কার্যকর করবে তবে আপনার যা প্রয়োজন তা হ'ল:
Class.forName("Somthing");
2: আপনি যদি ক্লাসটি লোড করতে আগ্রহী হন, এর স্ট্যাটিক ব্লকগুলি কার্যকর করুন এবং এর অ স্থিত অংশটি অ্যাক্সেস করতে চান, তবে আপনার একটি উদাহরণ প্রয়োজন এবং তারপরে আপনার প্রয়োজন:
Class.forName("Somthing").newInstance();
"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());
কেবলমাত্র উপরের উত্তরের সাথে যুক্ত করা, যখন আমাদের কাছে একটি স্ট্যাটিক কোড থাকে (যেমন কোড ব্লক উদাহরণ স্বতন্ত্র) যা মেমরিতে উপস্থিত থাকতে হবে, আমরা ক্লাসটি ফিরিয়ে আনতে পারি তাই আমরা Class.forname ("কিছু নাম") ব্যবহার করব অন্যথায় যদি আমরা স্ট্যাটিক কোড নেই যা আমরা Class.forname ()। newInstance ("someName") এর জন্য যেতে পারি কারণ এটি মেমরিটিতে অবজেক্ট লেভেল কোড ব্লকগুলি (অ স্থিতিশীল) লোড করবে as
আপনি ক্লাস.ফরনাম () পদ্ধতিটি কতবার কল করেন তা নয়, কেবল একবার স্ট্যাটিক ব্লক একাধিকবার কার্যকর করা হয় না:
নেমমেথডেমো জন্য প্যাকেজ;
পাবলিক ক্লাস মেইনক্লাস {
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
বিবৃতিটি তিনবার নয় একবারই মুদ্রিত হয়েছে।
Class.forName () -> forName () ক্লাস শ্রেণীর স্থির পদ্ধতি এটি প্রতিচ্ছবি হিসাবে ব্যবহৃত শ্রেণীর শ্রেণীর অবজেক্ট ব্যবহারকারী শ্রেণীর অবজেক্টকে দেয় না তাই আপনি কেবল এটিতে ক্লাস ক্লাস পদ্ধতিগুলি কল করতে পারেন যেমন getMethods (), getConstructors () ইত্যাদি etc.
আপনি যদি আপনার (রানটাইম প্রদত্ত) শ্রেণীর কেবল স্ট্যাটিক ব্লকটি চালানোর বিষয়ে চিন্তা করেন এবং কেবল আপনার ক্লাসের পদ্ধতি, নির্মাতা, সংশোধক ইত্যাদির তথ্য পান তবে আপনি ক্লাস.ফোর্নাম () ব্যবহার করে এই অবজেক্টটি দিয়ে করতে পারেন)
তবে আপনি যদি নিজের ক্লাস পদ্ধতিটি অ্যাক্সেস করতে বা কল করতে চান (রানটাইমের সময় আপনি যে ক্লাসটি দিয়েছিলেন) তবে আপনার অবজেক্টটি এত তাড়াতাড়ি করা দরকার ক্লাস ক্লাসের নতুন পদ্ধতি পদ্ধতিটি আপনার জন্য করা উচিত t এটি ক্লাসের নতুন উদাহরণ তৈরি করে আপনাকে তা ফেরত দেবে .এটি আপনার ক্লাসে টাইপ-কাস্ট করা দরকার।
উদাহরণস্বরূপ: ধরুন কর্মচারী তখন আপনার ক্লাস
শ্রেণি a = Class.forName (আরগস [0]);
// আরগস [0] = রানটাইমের সময় শ্রেণি দেওয়ার জন্য লিমিটেড লাইন সেমি।
কর্মচারী ob1 = a.newInstance ();
a.newInstance () নতুন কর্মচারী () ব্যবহার করে অবজেক্ট তৈরি করার অনুরূপ।
এখন আপনি আপনার সমস্ত শ্রেণীর দৃশ্যমান ক্ষেত্র এবং পদ্ধতিগুলি অ্যাক্সেস করতে পারেন।