جاوا ۱۰ — استنتاج نوع متغیر‌های محلی (Local Type Inference)

در جاوا برای تعریف یک متغیر، لازم است تا نوع متغیر در تعریف مشخص باشد:

List<String> list = new ArrayList<>();
Stream<String> stream = list.stream();

در جاوا ۱۰، یک متغیر می‌تواند به صورتی تعریف شود که نوع آن به شکل خودکار توسط کامپایلر جاوا استنتاج (Infer) گردد. این کار با به کار گرفتن var ممکن است:

var list = new ArrayList<String>();     // list: Class<List<String>>
var stream = list.stream();             // stream: Class<Stream<String>>

چند نکته در مورد var:

این ویژگی تأثیر زیادی بر روی خوانایی کد خواهد داشت. اما مهم‌تر از آن این ویژگی دو قابلیت را به زبان جاوا اضافه خواهد کرد که سال‌های زیادی برای آن انتظار هست.

انواع غیر‌کاربردی (Impractical Types)

در تکه کد فرضی پایین می‌خواهیم خلاصه‌ای از نمرات دانشجویان بر اساس درس آنها پیدا کنیم؛ این کد بر اساس امکانات موجود در جاوا ۸ نوشته شده:

List<ExamSummary> 
    summaries = dbApi
        .select(course.name, student.name, exam.score)
        .from(course, student, exam)
        .groupBy(course.type, student.name)
    .stream()
    .map(row -> convertToExamSummary(row))
    .collect(toList())

سؤال جالب در کد بالا این‌ است که اگر ما بخواهیم با متغیر row بیشتر کار کنیم، نوع این متغیر چه می‌تواند باشد؟

در یک حالت می‌توان این طور استدلال کرد که نیاز به یک کلاس میانی (Intermdiate Type) هست که در واقع بازتابی از جداول ادغام شده داده‌ها می‌باشد. این کلاس در صورت وجود ارزش آن همیشه منوط به تغییرات کد بالا هست و عملا کاربرد دیگری ندارد.

در حالتی دیگر می‌توان سعی کرد فقط از کتابخانه‌های جاوا استفاده کرد؛ به طور مثال ممکن است بتوان متغیر row را از نوع Map<String, Map<String, List<<Double>> تعریف کرد چرا که در واقع بازتاب مقادیر برگشتی از عملیات داده‌ای می‌باشد.

در هر دو حالت بالا نوع تعریف شده برای متغیر row به شکلی است که یا خوانایی پایینی دارد و یا این که کاربردی به جز این حوزه نخواهد داشت و بر این اساس یک نوع غیر‌کاربردی (Impractical) محسوب می‌شود.

در جاوا ۱۰ به صورت خودکار نوع متغیر row استنتاج شده و برنامه‌نویس می‌تواند بدون نیاز به انواع تعریفی جداگانه از این انواع استفاده کند.

انواع غیر‌ممکن (Impossible Types)

کد زیر تا قبل از جاوا ۱۰ را در نظر بگیرید:

Object student = new Object() {
    String name = "Student";
    int id = 1;
}

این کد معمولا در جاوا به عنوان کلاس یا شی داخلی بینام (Annonymous Inner Class) نامیده می‌شود. این به معنی‌ست که فقط در حوزه تعریف این نوع بالا می‌توان به متغیر‌های name و id دسترسی داشت.

در جاوا ۱۰ می‌توان کد بالا را به شکل زیر نوشت:

var student = new Object() {
    String name = "Student";
    int id = 1;
}

با این طرز تعریف حالا شما در خارج این تعریف می‌توانید به name و id دسترسی داشته باشید چرا که جاوا آن را به عنوان یک نوع جدید شناسایی می‌کند:

System.out.println(student.name);

این ویژگی باعث می‌شود که انواعی که قبلا استفاده از آنها غیر‌ممکن (Impossible Types) بود، به سادگی ممکن شده و حتی کمک می‌کند که انواع ترکیبی دیگری نیز به راحتی قابل استفاده باشد.

درباره این ویژگی می‌توانید در اینجا بیشتر مطالعه کنید.

به نظر شما نوع متغیر list در کد زیر چیست؟

var list = List.of("a", 1);