JavaRush /مدونة جافا /Random-AR /بيان الإرجاع في جافا
Viacheslav
مستوى

بيان الإرجاع في جافا

نشرت في المجموعة

مقدمة

كما نعلم، جافا هي لغة برمجة كائنية التوجه. وهذا هو المفهوم الأساسي، لأن القول بأن أساس الأساسيات هو أن كل شيء هو كائن. يتم وصف الكائنات باستخدام الفئات. بيان الإرجاع في جافا - 1الطبقات بدورها لها حالة وسلوك. على سبيل المثال، قد يكون للحساب البنكي حالة على شكل مبلغ من المال في الحساب وله سلوك زيادة الرصيد وتقليله. يتم تنفيذ السلوك في Java باستخدام الأساليب. يتم تقديم كيفية وصف الأساليب في بداية رحلة تعلم Java. على سبيل المثال، في البرنامج التعليمي الرسمي من Oracle: " Defining Methods ". هناك جانبان مهمان هنا:
  • كل طريقة لها توقيع. يتكون التوقيع من اسم الطريقة ومعلمات الإدخال الخاصة بها؛
  • يجب أن تحدد الأساليب نوع الإرجاع؛
  • نوع الإرجاع ليس جزءًا من توقيع الطريقة.
مرة أخرى، هذا نتيجة لحقيقة أن Java هي لغة مكتوبة بقوة ويريد المترجم أن يفهم مسبقًا الأنواع المستخدمة قدر الإمكان. مرة أخرى، لحمايتنا من الأخطاء. بشكل عام، كل شيء للخير. حسنًا، يبدو لي أن هذا يغرس فينا مرة أخرى ثقافة التعامل مع البيانات. لذلك، بالنسبة للطرق يتم تحديد نوع القيمة. ولإرجاع نفس القيمة من الطرق، يتم استخدام الكلمة الأساسية return.

بيان إرجاع الكلمات الرئيسية في جافا

تشير الكلمة الأساسية للبيان returnإلى "بيانات التحكم في التدفق" كما تمت مناقشتها في برنامج Oracle التعليمي " بيانات التحكم في التدفق ". يمكنك أيضًا أن تقرأ عن كيفية إرجاع القيم في البرنامج التعليمي الرسمي: " إرجاع قيمة من طريقة ". يراقب المترجم بعناية، قدر استطاعته، أن القيمة التي يتم إرجاعها من إحدى الطرق تتطابق مع نوع قيمة الإرجاع المحدد بواسطة الطريقة. دعونا نستخدم IDE عبر الإنترنت من موقع Tutorialspoint كمثال . دعونا نلقي نظرة على المثال الأصلي:
public class HelloWorld {
    public static void main(String []args) {
        System.out.println("Hello World");
    }
}
كما نرى، يتم تنفيذ طريقة هنا main، وهي نقطة الدخول إلى البرنامج. يتم تنفيذ أسطر التعليمات البرمجية من الأعلى إلى الأسفل. لا يمكن لطريقتنا mainإرجاع القيم، وإلا فسنتلقى خطأ: " Error: Main method must return a value of type void". لذلك، سيتم إخراج الطريقة ببساطة إلى الشاشة. لننقل الآن استلام السلسلة إلى طريقة منفصلة لتلقي الرسالة:
public class HelloWorld {

    public static void main(String []args) {
        System.out.println(getHelloMessage());
    }

    public static String getHelloMessage() {
        return "Hello World";
    }

}
كما نرى، باستخدام الكلمة الأساسية returnقمنا بتحديد القيمة المرجعة، والتي استخدمناها لاحقًا في الطريقة println. وقد أشرنا في وصف (تعريف) الطريقة getHelloMessageإلى أنها ستعيدنا String. يسمح هذا للمترجم بالتحقق من أن إجراءات الطريقة متوافقة مع الطريقة التي تم الإعلان عنها. وبطبيعة الحال، يمكن أن يكون نوع القيمة المرجعة المحددة في تعريف الطريقة أوسع من نوع القيمة التي يتم إرجاعها من الكود، أي. الشيء الرئيسي هو أن الأنواع يتم اختزالها مع بعضها البعض. وإلا فسوف نحصل على خطأ في وقت الترجمة: " error: incompatible types". بالمناسبة، ربما نشأ السؤال على الفور: لماذا returnينطبق ذلك على مشغلي التحكم في تدفق البرنامج؟ ولكن لأنه يمكن أن يعطل التدفق الطبيعي للبرنامج من الأعلى إلى الأسفل. على سبيل المثال:
public class HelloWorld {

    public static void main(String []args){
        if (args.length == 0)  {
            return;
        }
        for (String arg : args)  {
            System.out.println(arg);
        }
    }

}
كما يتبين من المثال، فإننا نقوم بمقاطعة تنفيذ الطريقة mainإذا تم استدعاء برنامج Java الخاص بنا بدون معلمات. من المهم أن تتذكر أنه إذا كان لديك returnالرمز، فسيصبح غير قابل للوصول. وسوف يلاحظ مترجمنا الذكي ذلك ولن يسمح لك بتشغيل مثل هذا البرنامج. على سبيل المثال، لن يتم تجميع هذا الرمز:
public static void main(String []args) {
        System.out.println("1");
        return;
        System.out.println("2");
 }
هناك اختراق قذر للالتفاف على هذا. على سبيل المثال، لأغراض التصحيح أو لسبب آخر. يمكن إصلاح الكود أعلاه عن طريق تغليفه returnفي ifكتلة:
if (2==2)  {
    return;
}

بيان الإرجاع في معالجة الأخطاء

هناك ظرف واحد صعب للغاية - يمكننا استخدامه returnمع معالجة الأخطاء. أود أن أقول على الفور أن استخدامه returnفي catchكتلة هو شكل سيء للغاية، لذا يجب عليك تجنبه. لكننا بحاجة إلى مثال، أليس كذلك؟ هنا هو:
public class HelloWorld  {

    public static void main(String []args) {
        System.out.println("Value is: " + getIntValue());
    }

    public static int getIntValue()  {
        int value = 1;
        try {
            System.out.println("Something terrible happens");
            throw new Exception();
        } catch (Exception e) {
            System.out.println("Catched value: " + value);
            return value;
        } finally {
            value++;
            System.out.println("New value: " + value);
        }
    }

}
للوهلة الأولى، يبدو أنه يجب إرجاع 2، لأنه finallyيتم تنفيذه دائمًا. finallyلكن لا، ستكون القيمة 1، وسيتم تجاهل التغيير الذي تم إجراؤه على المتغير . علاوة على ذلك، إذا كان valueيحتوي على كائن وقلنا finally، value = nullفسيظل catchيُرجع مرجعًا إلى الكائن، وليس null. ولكن من الكتلة كان finallyالمشغل returnسيعمل بشكل صحيح. من الواضح أن زملائك لن يشكروك على هذه الهدية.
ماذا تقرأ:

بيان العودة

void.class

وأخيرا. يمكنك كتابة بناء غريب مثل void.class. يبدو، لماذا وما هي النقطة؟ في الواقع، في مختلف الأطر والحالات الصعبة حيث يتم استخدام Java Reflection API ، قد يكون هذا ضروريًا للغاية. على سبيل المثال، يمكنك التحقق من النوع الذي تُرجعه الطريقة:
import java.lang.reflect.Method;

public class HelloWorld {

    public void getVoidValue() {
    }

    public static void main(String[] args) {
        for (Method method : HelloWorld.class.getDeclaredMethods()) {
            System.out.println(method.getReturnType() == void.class);
        }
    }
}
يمكن أن يكون هذا مفيدًا في أطر الاختبار حيث يكون من الضروري استبدال الكود الحقيقي للطرق. لكن للقيام بذلك، عليك أن تفهم كيف تتصرف هذه الطريقة (أي الأنواع التي تُرجعها). هناك طريقة ثانية لتنفيذ الطريقة mainمن الكود أعلاه:
public static void main (String[] args) {
        for (Method method : HelloWorld.class.getDeclaredMethods()) {
            System.out.println(method.getReturnType() == Void.TYPE);
        }
 }
يمكن قراءة مناقشة مثيرة للاهتمام حول الفرق بينهما في Stackoverflow: ما الفرق بين java.lang.Void وvoid؟ # فياتشيسلاف
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION