زبان های برنامه نویسی برای این که از رقابت شدید بین خودشان جا نمانند و برنامه نویسان آنها را کنار نگذارند باید همیشه خود را بروز کنند و قابلیت هایی را برای بهبود استفاده از زبان برنامه نویسی ارائه کنند. زبان برنامه نویسی جاوا|Java که دهه سوم عمر خود را می گذراند نیز سعی کرده است که از این رقابت بین زبان های برنامه نویسی جا نماند و همیشه در بازار حرفی برای گفتن داشته باشد که می توان گفت نسبتا خوب عمل کرده است. از زمانی که توسعه و پشتیبانی این زبان به دست شرکت اوراکل افتاد این زبان پیشرفت های قابل ملاحظه ای داشته است. در این مطلب قابلیت هایی را که از نسخه 8 جاوا تا نسخه 16 را که در سال 2021 ارائه شده است را بررسی می کنیم.
در نسخه 8 جاوا| Java برنامه نویسی تابعی و عبارات لامبدا Lambda به این زبان اضافه شد. در برنامه نویسی تابعی داده ها از پایپلاین ها عبور می کنند که هرکدام از این مراحل پایپلاین تغییراتی در داده ها به وجود می آورند و سرانجام به صورت یک خروجی نگاشت می شوند. به عبارت ساده تر در برنامه نویسی تابعی شما در مراحل مختلف تغییراتی را روی داده ها انجام می دهید و یک خروجی از آن می سازید. در جاوا با استفاده از Stream ها و Optional ها می توانید از مزایای Functional Programming استفاده کنید.
در بیشتر برنامه های کامپیوتری شما با یک لیست از مقادیر کار می کنید که یک پردازش روی آن انجام می دهید و هرکدام از این مقادیر و یا بعضی از آنها را تغییر می دهید. قبل از نسخه 8 جاوا شما از حلقه هایی مانند for برای این کار استفاده می کردید. اما از نسخه 8 جاوا به بعد و با استفاده از قابلیت برنامه نویسی تابعی و لامبدا و با استفاده از Stream ها این کار را به شکل زیر انجام می دهید.
Stream.of("hello", "great")
.map(s -> s + " world")
.forEach(System.out::println);
//output
> hello world
> great world
در کد بالا یک لیست دو تایی رشته ای می سازیم و کلمه world را به انتهای آن اضافه کرده و آن را چاپ می کنیم. تابع map یک عبارت لامبدا را به عنوان ورودی دریافت می کند و آن را بر روی همه ورودی ها اعمال می کند.
استریم ها را می توان در لیست ها و Set ها و Map ها استفاده کرد. با استفاده از استریم می توانید از دست بسیاری از حلقه های پیچیده و طولانی خلاص شوید.
یادگیری برنامه نویسی برای متخصصین حوزه کامپیوتر این روزها یک الزام به حساب می آید. از جمله محبوب ترین زبان های برنامه نویسی دنیا می توانیم به زبان برنامه نویسی سی شارپ ، زبان برنامه نویسی جاوا ، زبان برنامه نویسی پایتون ، زبان برنامه نویسی سی پلاس پلاس و زبان برنامه نویسی SQL ( لازمه هر زبان دیگری ) و زبان برنامه نویسی PHP اشاره کنیم.
برای آموزش برنامه نویسی می توانید با خیال راحت در قالب دوره های آموزش برنامه نویسی سایت توسینسو ، آموزش سی شارپ ، آموزش جاوا ، آموزش پایتون ، آموزش جنگو ، آموزش PHP ، آموزش جاوا اسکریپت ، آموزش برنامه نویسی اندروید ، آموزش SQL و آموزش MySQL را بصورت جامع و حرفه ای آموزش ببینید.
یکی از مشکلات رایج در جاوا خطای Null Pointer Exception بود. این خطا زمانی رخ می داد که شیئی که با آن کار می کردیم در برنامه null بود. برای حل این مشکل مفهوم Optional در جاوا معرفی شد. در استفاده از optional مشخص می کنیم که اگر شی وجود دارد و مقدارش null نیست کار ما ادامه پیدا کند و در صورت null بودن تصمیم مربوط به آن گرفته شود. نحوه استفاده از Optional به این شکل است.
Optional.of(new Random().nextInt(10))
.filter(i -> i % 2 == 0)
.map(i -> "number is even: " + i)
.ifPresent(System.out::println);
// output
> number is even: 6
در کد بالا ما یک عدد تصادفی تولید می کنیم و اگر عدد مورد نظر زوج بود آن را چاپ می کنیم.
خیلی از زبان ها دارای یک خط فرمان هستند که دستورات تک خطی را اجرا می کند مانند پایتون و جاوااسکریپت و خیلی از زبان های دیگر. به این ابزار خط فرمان که دستورات زبان برنامه نویسی را اجرا می کنند REPL می نامند. زبان جاوا نیز از نسخه 9 به بعد ابزاری به نام JShell معرفی کرده است. با استفاده از JShell شما می توانید کدهای خود را بدون آن که در کلاس بنویسید و کامپایل کنید اجرا کنید و نتیجه آن را ببینید. فقط یک خط کد جاوا را بنویسید و اینتر را بزنید آن کد اجرا خواهد شد. با این ابزار شما می توانید متغیر معرفی کنیدو کلاس تعریف کنید و از آن استفاده کنید و از قابلیت های دیگر جاوا استفاده کنید. یکی از قابلیت های جالب این ابزار امکان auto-completion است که خود کد شما را تکمیل می کند فقط کافیست چند حرف اول دستور را بنویسید و کلید تب را بزنید. کد زیر نمونه ای از این ابزار است.
jshell> System.out.println("Hello Tosinso users")
Hello Tosinso users
jshell> var a=15
a ==> 15
jshell> System.out.println(a)
15
مقداردهی اولی لیست ها قبلا به شکل زیر بود
jshell> List<Integer> list = Arrays.asList(1, 2, 3, 4)
list ==> [1, 2, 3, 4]
اما این روش تغییر کرده و از ورژن 9 جاوا به شکل زیر نوشته می شود
jshell> List<Integer> list = List.of(1, 2, 3, 4)
b ==> [1, 2, 3, 4]
شما از متد جالب of می توانید برای لیست ها و set ها و Map ها استفاده کنید. به همین راحتی!
برای ساخت متغیر یا شی جدید دیگر لازم نیست که که نوع متغیر را قبل از آن بیاوریم و می توانیم به جای آن از کلمه کلیدی var استفاده کنیم. این قابلیت در زبان هایی مانند سی شارپ از قبل وجود داشت ولی جاوا آن را از نسخه 10 به بعد اضافه کرده است. در این روش خود کامپایلر با توجه به مقدار اولیه ای که داخل شی یا متغیر ریخته می شود نوع آن را شناسایی می کند. مانند کد زیر
jshell> var x = new HashSet<String>()
x ==> []
jshell> x.add("apple")
$1 ==> true
دقت کنید که از کلمه کلیدی var فقط می توان داخل بدنه متد استفاده کرد و بقیه جاها باید از روش قبلی استفاده نمود.
اگر برنامه جاوا ما در یک فایل جاوا جا داده شده باشد. قبلا برای اجرای آن توسط خط فرمان باید اول آن را کامپایل می کردیم واز داخل آن فایل class می ساختیم که حاوی بایت کد بود و سپس آن را اجرا می کردیم. ولی از جاوا ۱۱ به بعد با یک خط می توان برنامه را کامپایل و اجرا نمود برای مثال اگر برنامه ای به شکل زیر در یک فایل به نام Main.java داشته باشیم.
public class Main {
public static void main(String[] args) {
System.out.println("hello world");
}
}
می توانیم با دستور زیر آن را اجرا کنیم.
$ java ./Main.java
hello world
عبارت switch در جاوا 12 اضافه شده است که به شکل زیر کار می کند. اگر قبلا می خواستیم با استفاده از switch تصمیم بگیریم که چه مقداری به یک متغیر بدهیم به روش زیر عمل می کردیم.
jshell> var i = 3
jshell> String s;
jshell> switch(i) {
...> case 1: s = "one"; break;
...> case 2: s = "two"; break;
...> case 3: s = "three"; break;
...> default: s = "unknown number";
...> }
jshell> s
s ==> "three"
ولی از نسخه 12 جاوا به بعد می توانیم از روش زیر نیز استفاده کنیم.
jshell> var i = 3;
jshell> var x = switch(i) {
...> case 1 -> "one";
...> case 2 -> "two";
...> case 3 -> "three";
...> default -> "unknown number";
...> };
x ==> "three"
فقط در استفاده از این روش به نکات زیر دقت کنید.
اگر با مقادیر رشته ای طولانی مانند عبارات json کار کرده باشید در جاوا یا مجبور بودیم که کل رشته را در یک خط قرار بدهیم یا در انتهای خط رشته را می بستیم و بقیه را با علامت + در خط بعدی می نوشتیم. اما در جاوا 13 می توانید به شکل زیر رشته های چند خطی داشته باشید و از آنها استفاده کنید.
public class Main {
public static void main(String [] args) {
var s = """
{
"recipe": "watermelon smoothie",
"duration": "10 mins",
"items": ["watermelon", "lemon", "parsley"]
}""";
System.out.println(s);
}
}
برخی اوقات کلاس هایی را تعریف می کنیم که متدی ندارند و فقط کلاس مربوطه برای نگهداری داده ها است. خب برای آنها باید فیلد ها تعریف می شد و getter , setter تعریف می شود و متد equals هم گاهی لازم بود تا override شود. اما در جاوا 14 قابلیت جدیدی به نام record ارائه شده است که دیگر نیازی به خیلی از کارهایی که گفتیم نیست و شما فقط نوع فیلد ها را مشخص می کنید. کد زیر مثالی از این قابلیت است.
jshell> record Employee (String name, int age, String department) {}
| created record Employee
jshell> var x = new Employee("Anne", 25, "Legal");
x ==> Employee[name=Anne, age=25, department=Legal]
jshell> x.name()
$2 ==> "Anne"
قبلا هم در جاوا قابلیت instanceof وجود داشت ولی به شکل زیر استفاده می شد.
Object obj = new String("hello");
if (obj instanceof String) {
System.out.println("String length: " + ((String)obj).length());
}
مشکلی که این روش داشت این بود که ابتدا چک می کردیم که s از نوع String هست یا خیر سپس دوباره آن را cast می کردیم که بتوانیم مقادیر رشته ای آن را دریافت کنیم
اما از جاوا 14 به بعد می توانیم از این روش استفاده کنیم.
Object obj = new String("hello");
if (obj instanceof String mystr) {
System.out.println("String length: " + mystr.length());
}
با استفاده از کلمه کلیدی sealed می توانید مشخص کنید که کدام کلاس ها می توانند از کلاس یا اینترفیس شما ارث بری داشته باشند به نوعی کلاس هایی را که از کلاس یا اینترفیس شما ارث بری دارند را محدود می کنید. مانند کد زیر
public sealed interface Fruit permits Apple, Pear {
String getName();
}
public final class Apple implements Fruit {
public String getName() { return "Apple"; }
}
public final class Pear implements Fruit {
public String getName() { return "Pear"; }
}
در جاوا 16 سعی شده است که قابلیت های record, sealed class, instanceof بهبود داده شود و بهینه سازی هایی در این موارد انجام شده است. زیرا که این قابلیت ها حالت preview در نسخه های قبلی داشتند که بسیاری در نسخه 16 نهایی شده اند و مشکلات آنها برطرف شده است.
با وب سایت Tosinso همراه باشید.
بنیانگذار توسینسو و برنامه نویس
مهدی عادلی، بنیان گذار TOSINSO. کارشناس ارشد نرم افزار کامپیوتر از دانشگاه صنعتی امیرکبیر و #C و جاوا و اندروید کار می کنم. در زمینه های موبایل و وب و ویندوز فعالیت دارم و به طراحی نرم افزار و اصول مهندسی نرم افزار علاقه مندم.
زمان پاسخ گویی روز های شنبه الی چهارشنبه ساعت 9 الی 18
فقط به موضوعات مربوط به محصولات آموزشی و فروش پاسخ داده می شود