مهدی عادلی فر
بنیانگذار توسینسو و برنامه نویس

آموزش فراخوانی متدها در زمان اجرا در جاوا با Reflection

چگونه متدها را در زمان اجرا با استفاده از Reflection جاوا فراخوانی کنیم؟ یکی از قابلیت هایی که زبان های برنامه نویسی امروزی دارند این است که می توان کتابخانه هایی ساخت و از آنها در برنامه های مختلف استفاده کرد. اضافه کردن این کتابخانه ها به پروژه از دو راه امکان پذیر است. راه اول این است که هنگام برنامه نویسی و در هنگام نوشتن پروژه کتابخانه را به پروژه اضافه کنیم در این حالت برنامه آن کتابخانه را به راحتی شناسایی کرده و می تواند از آن استفاده کند. ولی مشکلی که این راه دارد این است که این کار فقط زمانی امکان پذیر است که ما در حال نوشتن پروژه باشیم.

دوره های شبکه، برنامه نویسی، مجازی سازی، امنیت، نفوذ و ... با برترین های ایران

یعنی اگر کار نوشتن پروژه تمام شده باشد و برنامه در حال اجرا باشد دیگر نمی توانیم از این روش استفاده کنیم. راه دیگر آن است که هنگام اجرای برنامه کتابخانه را معرفی کرده و به برنامه بگوییم که از کلاس ها و متدهای این برنامه استفاده کند. این روش با استفاده از یک مفهوم به نام reflection در زبان برنامه نویسی شدنی است. در این مطلب قصد داریم یک نمونه از reflection در جاوا را توضیح دهیم و بگوییم که چگونه می توان در زمان اجرا یک کتابخانه را گرفته و اجرا کرد. برای شروع کار ابتدا یک کلاس ساده در جاوا می سازیم که فقط یک متد داشته و عمل ساده جمع کردن دو عدد صحیح را انجام می دهد. کد این کلاس در ادامه آمده است.

public class TestClass {
    public int add(int a , int b){return a+b;}
}

همانطور که در کلاس بالا دیده می شود نام کلاس TestClass بوده و یک متد add دارد که این متد دارای دو ورودی عدد صحیح و مقدار خروجی عدد صحیح می باشد. بعد از نوشتن کلاس نوبت به کامپایل آن می رسد که شما هم می توانید از خط فرمان با استفاده از کامپایلر جاوا که همان javac است این کلاس را کامپایل کنید و یا از طریق یک IDE مانند intellij از منوی build گزینه build را انتخاب کنید تا کلاس نوشته شده کامپایل شده و یک فایل با پسوند .class تولید شود. اگر IDE در اختیار ندارید و می خواهید با استفاده از javac این فایل را کامپایل کنید از دستور زیر در cmd یا خط فرمان استفاده کنید.

Javac TestClass.java

بعد از ساخته شدن فایل .class باید یه این نکته دقت داشت که کتابخانه های جاوا معمولا فایل هایی با پسوند .jar هستند. این فایل های .jar همان فایل های فشرده zip هستند که فقط پسوند آنها تغییر داده شده است. پس شما می توانید با این فایل ها مانند فایل های zip رفتار کنید. ما نیز برای این کار فایل .class ساخته شده را در یک فایل zip قرار می دهیم. دقت کنید که لازم نیست که پسوند فایل zip را به jar تغییر دهید. تا به اینجا ما یک فایل کامپایل شده را در یک فایل zip قرار دادیم. حال می خواهیم هنگام اجرای برنامه فایل Zip مورد نظر را باز کرده و فایل کلاس را از داخل آن بخوانیم و متد add را از آن اجرا کنیم و نتیجه را ببینیم.

برای این کار یک پروژه جدید شروع می کنیم و یک کلاس جدید می سازیم که حاوی متد main باشد. حال در داخل متد main باید از فایل zip یک نمونه بسازیم تا بتوانیم از فایل های داخل آن استفاده کنیم. خوشبختانه جاوا به راحتی می تواند با فایل های زیپ کار کند و محتویات داخل آن را به راحتی شناسایی می کند. برای این کار ابتدا یک URL می سازیم که آدرس کلاس کامپایل شده در داخل فایل زیپ را به عنوان ورودی دریافت می کند. برای مثال فایل زیپ من در درایو D ذخیره شده و نام آن TestClass.zip می باشد. کد این قسمت به شکل زیر است

URL url = new URL("jar:file:" + "d:"+ File.pathSeparator+"TestClass.zip" + "!/TestClass.class");
URL[] urls = {url};

دقت کنید که File.pathSeparator برای جدا کردن پوشه ها و فایل ها می باشد که در ویندوز علامت بک اسلش \\ و در لینوکس علامت / است. ولی استفاده از File.pathSeparator خود می داند که از چه علامتی برای جدا کردن استفاده کند.پس از این که آدرس را اضافه کردیم باید کلاس مورد نظر را لود کنیم. لود کردن کلاس با استفاده از URLClassLoader انجام می شود. بخش لود کردن کلاس را باید به شکل زیر نوشت

URLClassLoader loader=  URLClassLoader.newInstance(urls);
Class cl= loader.loadClass("TestClass");

بعد از این بخش باید متد مورد نظر را اجرا کنیم. برای اجرای متد باید نام آن و همچنین نوع داده پارامترهای ورودی را نیز به عنوان مشخصات متد وارد کنیم و سپس متد مورد نظر را با دستور invoke اجرا کنیم که کد آن به شکل زیر است.

Method mm=cl.getMethod("add",int.class,int.class);
Object invoke = mm.invoke(cl.newInstance(), 25, 52);
System.out.println(invoke);

در کد بالا با استفاده از getMethod متد add را گرفته و دو پارامتر ورودی را مشخص کرده ایم. سپس آن را اجرا کرده ایم. دقت کنید که newInstance یک شئ از کلاس مورد نظر می سازد. کد کامل اجرای این برنامه به شکل زیر است.

public static void main(String[] args){

    try {
        URL url = new URL("jar:file:" + "d:"+ File.pathSeparator+"TestClass.zip" + "!/TestClass.class");
        URL[] urls = {url};
        URLClassLoader loader=  URLClassLoader.newInstance(urls);
        Class cl= loader.loadClass("TestClass");

        Method mm=cl.getMethod("add",int.class,int.class);
        Object invoke = mm.invoke(cl.newInstance(), 25, 52);
        System.out.println(invoke);
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    }

}

دقت کنید که بخش های مختلف این برنامه ممکن است که exception بدهد که در بخش های catch باید این exception ها مدیریت شوند. خروجی این برنامه حاصل جمع 52 , 25 یعنی 77 خواهد بود.

ITPRO باشید.

نویسنده: مهدی عادلی فر

منبع: Itpro

هرگونه نشر و کپی برداری بدون ذکر منبع و نام نویسنده دارای اشکال اخلاقی می باشد.


مهدی عادلی فر
مهدی عادلی فر

بنیانگذار توسینسو و برنامه نویس

مهدی عادلی، بنیان گذار TOSINSO. کارشناس ارشد نرم افزار کامپیوتر از دانشگاه صنعتی امیرکبیر و #C و جاوا و اندروید کار می کنم. در زمینه های موبایل و وب و ویندوز فعالیت دارم و به طراحی نرم افزار و اصول مهندسی نرم افزار علاقه مندم.

نظرات