آمادگی یعنی:
مهارتهای لازم را یاد گرفته باشی،
زبان بلد باشی،
ظرفیتهای شخصی و حرفهایات را پرورش داده باشی.
وگرنه حتی اگر همین امروز اعلام کنند:
«به متخصص جاوا در یک شرکت معتبر داخلی یا خارجی نیاز داریم»
باید از خودت بپرسی:
⚡️ @javapro_ir✈️ @group_javapro
Please open Telegram to view this post
VIEW IN TELEGRAM
تمامی جلسات مینی دوره اپلیکیشن TODO با فریمورک Spring Boot را در کانال یوتیوب جاواپرو می توانید به صورت یکجا و فهرست بندی شده تماشا کنید.
⬇️ جهت مشاهده روی لینک زیر کلیک کنید:
▶️ مشاهده
👤 کانال یوتیوب جاواپرو رو دوست داشتید سابسکرایب کنید چون دوره های رایگان جاوا رو در اینجا هم قرار میدیم.
➡️ اشتراک 👍 لایک 💬 کامنت
⚡️ @javapro_ir✈️ @group_javapro
Please open Telegram to view this post
VIEW IN TELEGRAM
🧠 مدل حافظه در جاوا (Java Memory Model) و نقش volatile
مدل حافظه در جاوا یا JMM مشخص میکند که چگونه Threadها به حافظه دسترسی دارند و چه زمانی تغییرات در متغیرها توسط سایر Threadها دیده میشود.
این موضوع اهمیت زیادی در برنامههای همزمان (Concurrent) دارد، چون بدون آن نتایج غیرقابل پیشبینی رخ خواهد داد.
📌 مسئلهی اصلی: Visibility و Reordering
برنامههای چندنخی در جاوا روی پردازندهها اجرا میشوند و پردازندهها برای افزایش سرعت، دستورها را ممکن است بازچینی (Reorder) کنند. همچنین هر Thread معمولاً دادهها را در Cache محلی خودش نگه میدارد.
به همین دلیل دو مشکل اصلی ایجاد میشود:
Visibility (قابلیت مشاهده):
یک Thread مقدار جدید متغیر را تغییر میدهد اما سایر Threadها همچنان مقدار قدیمی را میبینند.
Reordering (بازچینی):
دستورها توسط CPU یا کامپایلر جابهجا میشوند و در نتیجه Thread دیگر ترتیب مورد انتظار را نمیبیند.
✅ نقش volatile
کلمهی کلیدی volatile به جاوا میگوید که:
1. همیشه مقدار متغیر از حافظه اصلی (Main Memory) خوانده شود.
2. هر تغییر در متغیر بلافاصله برای سایر Threadها قابل مشاهده باشد.
3. بازچینی دستورها (Reordering) برای دسترسی به این متغیر ممنوع شود.
🔎 مثال بدون volatile (رفتار اشتباه)
📌 مشکل:
در اینجا ممکن است Thread worker هیچوقت متوقف نشود، چون مقدار running در Cache Thread گیر کرده و تغییرش در Thread اصلی دیده نمیشود.
🔎 مثال با volatile (رفتار درست)
📌 توضیح:
با volatile تغییر مقدار متغیر running بلافاصله به حافظه اصلی فرستاده میشود.
بنابراین Thread worker بهمحض تغییر متغیر، مقدار جدید را میبیند و متوقف میشود.
🎯 جمعبندی
در واقع Java Memory Model مشخص میکند که Threadها چگونه حافظه را میبینند.
مشکلات اصلی در Multithreading Visibility و Reordering هستند.
کلیدواژه volatile تضمین میکند که تغییرات یک متغیر بلافاصله توسط همهی Threadها قابل مشاهده باشد و دستورات مربوط به آن بازچینی نشوند.
مدل حافظه در جاوا یا JMM مشخص میکند که چگونه Threadها به حافظه دسترسی دارند و چه زمانی تغییرات در متغیرها توسط سایر Threadها دیده میشود.
این موضوع اهمیت زیادی در برنامههای همزمان (Concurrent) دارد، چون بدون آن نتایج غیرقابل پیشبینی رخ خواهد داد.
📌 مسئلهی اصلی: Visibility و Reordering
برنامههای چندنخی در جاوا روی پردازندهها اجرا میشوند و پردازندهها برای افزایش سرعت، دستورها را ممکن است بازچینی (Reorder) کنند. همچنین هر Thread معمولاً دادهها را در Cache محلی خودش نگه میدارد.
به همین دلیل دو مشکل اصلی ایجاد میشود:
Visibility (قابلیت مشاهده):
یک Thread مقدار جدید متغیر را تغییر میدهد اما سایر Threadها همچنان مقدار قدیمی را میبینند.
Reordering (بازچینی):
دستورها توسط CPU یا کامپایلر جابهجا میشوند و در نتیجه Thread دیگر ترتیب مورد انتظار را نمیبیند.
✅ نقش volatile
کلمهی کلیدی volatile به جاوا میگوید که:
1. همیشه مقدار متغیر از حافظه اصلی (Main Memory) خوانده شود.
2. هر تغییر در متغیر بلافاصله برای سایر Threadها قابل مشاهده باشد.
3. بازچینی دستورها (Reordering) برای دسترسی به این متغیر ممنوع شود.
🔎 مثال بدون volatile (رفتار اشتباه)
public class WithoutVolatile {
private static boolean running = true;
public static void main(String[] args) throws InterruptedException {
Thread worker = new Thread(() -> {
while (running) {
// مشغول کار
}
System.out.println("Worker stopped!");
});
worker.start();
Thread.sleep(1000);
running = false; // تلاش برای توقف
System.out.println("Flag set to false");
}
}
📌 مشکل:
در اینجا ممکن است Thread worker هیچوقت متوقف نشود، چون مقدار running در Cache Thread گیر کرده و تغییرش در Thread اصلی دیده نمیشود.
🔎 مثال با volatile (رفتار درست)
public class WithVolatile {
private static volatile boolean running = true;
public static void main(String[] args) throws InterruptedException {
Thread worker = new Thread(() -> {
while (running) {
// مشغول کار
}
System.out.println("Worker stopped!");
});
worker.start();
Thread.sleep(1000);
running = false; // توقف درست انجام میشود
System.out.println("Flag set to false");
}
}
📌 توضیح:
با volatile تغییر مقدار متغیر running بلافاصله به حافظه اصلی فرستاده میشود.
بنابراین Thread worker بهمحض تغییر متغیر، مقدار جدید را میبیند و متوقف میشود.
🎯 جمعبندی
در واقع Java Memory Model مشخص میکند که Threadها چگونه حافظه را میبینند.
مشکلات اصلی در Multithreading Visibility و Reordering هستند.
کلیدواژه volatile تضمین میکند که تغییرات یک متغیر بلافاصله توسط همهی Threadها قابل مشاهده باشد و دستورات مربوط به آن بازچینی نشوند.
#کاربرـپیشرفته
🆔 @javapro_ir
🆔 @group_javapro
👍6
معرفی دوره
در اغلب وبسایتها بخشی برای ورود و ثبتنام کاربران وجود دارد. همچنین احتمالاً مشاهده کردهاید که برخی بخشها تنها برای کاربران خاصی در دسترس هستند. در این دوره یاد میگیرید چگونه با پیادهسازی یک سرویس IAM Service و استفاده از APIهای آماده، مفاهیم مربوط به Authorization را بهصورت عملی درک کرده و پیادهسازی کنید. در صورت وجود هرگونه سؤال یا مشکل نیز میتوانید آن را در گروه تلگرام پرسشوپاسخ مطرح کنید.
دستاوردهای دوره:
کار با JWT Token
پیادهسازی Authentication
مبانی Spring Security
این دوره برای افرادی طراحی شده است که به زبان Java در سطح مناسبی مسلط باشند.
آشنایی با Maven
سایر مفاهیم مربوط به Spring Boot در طول دوره آموزش داده خواهد شد.
https://youtu.be/56_a2d_LNrk
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
⚖️ تفاوت Checked و Unchecked Exceptions در جاوا
برنامهنویسی در جاوا بدون Exception Handling معنایی ندارد. جاوا برای مدیریت خطاها دو نوع Exception تعریف کرده است: Checked و Unchecked. این تمایز به ظاهر ساده است، اما تاثیر بزرگی بر طراحی APIها و ساختار کد دارد.
📌 Checked Exceptions
درواقع Checked Exception ها خطاهایی هستند که کامپایلر شما را مجبور میکند مدیریتشان کنید.
یا باید آنها را با try-catch بگیرید، یا باید با throws در امضای متد اعلام کنید.
این Exceptions معمولاً برای خطاهای قابل پیشبینی و بازیابیپذیر استفاده میشوند.
🔎 مثال:
📌 در این مثال، جاوا ما را مجبور میکند که IOException را مدیریت کنیم.
📌 Unchecked Exceptions
در واقع Unchecked Exception ها زیرکلاسهای RuntimeException هستند.
کامپایلر ما را مجبور به مدیریت آنها نمیکند.
این Exceptions معمولاً برای خطاهای برنامهنویسی مثل NullPointerException، ArrayIndexOutOfBoundsException یا IllegalArgumentException استفاده میشوند.
🔎 مثال:
📌 در اینجا هیچ اجباری از طرف کامپایلر برای مدیریت خطا وجود ندارد.
🎯 چرا این تمایز وجود دارد؟
در واقع Checked Exceptions به ما یادآوری میکنند که خطاهایی وجود دارند که باید آنها را جدی بگیریم (مثل IO یا دسترسی به شبکه).
و Unchecked Exceptions برای خطاهایی هستند که ناشی از اشتباه برنامهنویساند و معمولاً نباید recover شوند (مثل استفاده از null).
⚡ تاثیر روی طراحی APIها
اگر API شما با منابع خارجی (فایل، شبکه، دیتابیس) سروکار دارد → بهتر است Checked Exception برگرداند.
اگر API شما ورودی نامعتبر یا خطای منطقی دارد → معمولاً Unchecked Exception بهتر است.
🔎 مثال طراحی API:
✅ جمعبندی
Checked Exceptions →
قابل پیشبینی، باید مدیریت شوند.
Unchecked Exceptions →
خطاهای برنامهنویسی، اجباری برای مدیریت ندارند.
این تمایز باعث میشود APIها شفافتر باشند و توسعهدهنده بداند کجا باید به خطا اهمیت دهد.
برنامهنویسی در جاوا بدون Exception Handling معنایی ندارد. جاوا برای مدیریت خطاها دو نوع Exception تعریف کرده است: Checked و Unchecked. این تمایز به ظاهر ساده است، اما تاثیر بزرگی بر طراحی APIها و ساختار کد دارد.
📌 Checked Exceptions
درواقع Checked Exception ها خطاهایی هستند که کامپایلر شما را مجبور میکند مدیریتشان کنید.
یا باید آنها را با try-catch بگیرید، یا باید با throws در امضای متد اعلام کنید.
این Exceptions معمولاً برای خطاهای قابل پیشبینی و بازیابیپذیر استفاده میشوند.
🔎 مثال:
import java.io.*;
public class CheckedExample {
public static void main(String[] args) {
try {
FileReader reader = new FileReader("file.txt"); // FileNotFoundException
reader.read(); // IOException
} catch (IOException e) {
System.out.println("خطا: " + e.getMessage());
}
}
}
📌 در این مثال، جاوا ما را مجبور میکند که IOException را مدیریت کنیم.
📌 Unchecked Exceptions
در واقع Unchecked Exception ها زیرکلاسهای RuntimeException هستند.
کامپایلر ما را مجبور به مدیریت آنها نمیکند.
این Exceptions معمولاً برای خطاهای برنامهنویسی مثل NullPointerException، ArrayIndexOutOfBoundsException یا IllegalArgumentException استفاده میشوند.
🔎 مثال:
public class UncheckedExample {
public static void main(String[] args) {
String text = null;
System.out.println(text.length()); // NullPointerException
}
}
📌 در اینجا هیچ اجباری از طرف کامپایلر برای مدیریت خطا وجود ندارد.
🎯 چرا این تمایز وجود دارد؟
در واقع Checked Exceptions به ما یادآوری میکنند که خطاهایی وجود دارند که باید آنها را جدی بگیریم (مثل IO یا دسترسی به شبکه).
و Unchecked Exceptions برای خطاهایی هستند که ناشی از اشتباه برنامهنویساند و معمولاً نباید recover شوند (مثل استفاده از null).
⚡ تاثیر روی طراحی APIها
اگر API شما با منابع خارجی (فایل، شبکه، دیتابیس) سروکار دارد → بهتر است Checked Exception برگرداند.
اگر API شما ورودی نامعتبر یا خطای منطقی دارد → معمولاً Unchecked Exception بهتر است.
🔎 مثال طراحی API:
// Checked Exception: نشان میدهد که خطا قابل انتظار است
public void readFile(String path) throws IOException {
// ...
}
// Unchecked Exception: نشان میدهد که خطا ناشی از ورودی اشتباه است
public void setAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("سن نمیتواند منفی باشد");
}
}
✅ جمعبندی
Checked Exceptions →
قابل پیشبینی، باید مدیریت شوند.
Unchecked Exceptions →
خطاهای برنامهنویسی، اجباری برای مدیریت ندارند.
این تمایز باعث میشود APIها شفافتر باشند و توسعهدهنده بداند کجا باید به خطا اهمیت دهد.
#کاربرـحرفهـای
🆔 @javapro_ir
🆔 @group_javapro
👍5❤1
Spring Boot and Microservices.pdf
594.2 KB
Spring Boot و Microservices
این فایل پی دی اف درباره Spring Boot و معماری مایکروسرویسها هست. به طور خلاصه محتوای اون شامل موارد زیره:
اهمیت ساخت سیستمهای سریع، مقیاسپذیر و چابک در دنیای امروز.
معرفی Spring Boot بهعنوان یکی از بهترین و سادهترین پلتفرمها برای پیادهسازی مایکروسرویسها.
توضیح اصول کلیدی معماری مایکروسرویس مثل:
استقلال سرویسها (خرابی یک سرویس روی بقیه تأثیر نذاره).
استقلال نسخهها (هر سرویس با نسخه خودش کار کنه).
اختصاص دامین مشخص برای هر سرویس (مثلاً سرویس کاربر فقط مدیریت کاربران رو انجام بده).
انتخاب تکنولوژی مناسب برای هر سرویس بر اساس نیازش.
جداسازی کانتینر و دیتابیس برای هر سرویس.
داشتن فرآیند CI/CD مستقل برای هر سرویس.
رعایت قوانین ارتباط بین سرویسها و پروتکلهای مشخص.
مدیریت لاگ، امنیت و کنترل دسترسی برای هر سرویس بهطور مستقل.
در پایان هم یک نمونه پروژه e-commerce microservices در گیتهاب معرفی شده تا خواننده بتونه عملیتر موضوع رو ببینه.
➡️ اشتراک 👍 لایک 💬 کامنت
این فایل پی دی اف درباره Spring Boot و معماری مایکروسرویسها هست. به طور خلاصه محتوای اون شامل موارد زیره:
اهمیت ساخت سیستمهای سریع، مقیاسپذیر و چابک در دنیای امروز.
معرفی Spring Boot بهعنوان یکی از بهترین و سادهترین پلتفرمها برای پیادهسازی مایکروسرویسها.
توضیح اصول کلیدی معماری مایکروسرویس مثل:
استقلال سرویسها (خرابی یک سرویس روی بقیه تأثیر نذاره).
استقلال نسخهها (هر سرویس با نسخه خودش کار کنه).
اختصاص دامین مشخص برای هر سرویس (مثلاً سرویس کاربر فقط مدیریت کاربران رو انجام بده).
انتخاب تکنولوژی مناسب برای هر سرویس بر اساس نیازش.
جداسازی کانتینر و دیتابیس برای هر سرویس.
داشتن فرآیند CI/CD مستقل برای هر سرویس.
رعایت قوانین ارتباط بین سرویسها و پروتکلهای مشخص.
مدیریت لاگ، امنیت و کنترل دسترسی برای هر سرویس بهطور مستقل.
در پایان هم یک نمونه پروژه e-commerce microservices در گیتهاب معرفی شده تا خواننده بتونه عملیتر موضوع رو ببینه.
⚡️ @javapro_ir✈️ @group_javapro
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Please open Telegram to view this post
VIEW IN TELEGRAM
گاهی پیش میاد وسط مسیر یادگیری یا کار کدنویسی بیانگیزه بشیم. اما راهکارهایی وجود داره که کمک میکنه انگیزهمون پایدار بمونه:
1️⃣ با افراد همفکر معاشرت کن → وقتی اطرافت پر از کسایی باشه که روی پروژهها کار میکنن، تو هم ناخودآگاه وارد جریان میشی.
2️⃣ در رویدادها شرکت کن → دیدار با برنامهنویسها، استارتاپیها و متخصصان، انرژی و انگیزه زیادی میده.
3️⃣ استراحت رو فراموش نکن → کدنویسی بدون وقفه باعث فرسودگی میشه. با استراحت ذهن تازه میمونه.
4️⃣ رقابت کن → شرکت در چالشها و هکاتونها باعث رشد و یادگیری سریعتر میشه، حتی اگر برنده نشی.
5️⃣ آموزش بده → ضبط ویدئو یا نوشتن مقاله، علاوه بر یادگیری عمیقتر، باعث میشه دنبالکننده پیدا کنی و انگیزهات بیشتر بشه.
6️⃣ چیزهای جدید یاد بگیر → با امتحان تکنولوژیها و روشهای تازه، یادگیری همیشه جذاب و تازه میمونه.
✨ انگیزه در برنامهنویسی یک مسیر بلندمدته، با این عادتها میتونی پایدار و با انرژی پیش بری.
⚡️ @javapro_ir✈️ @group_javapro
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
این مباحث برای شرکت کنندگان قبلی دوره «رایگان» خواهد بود.
Please open Telegram to view this post
VIEW IN TELEGRAM
آکادمی جاواپرو
دوره طلایی Spring Core
این دوره به شما کمک میکند تا با مبانی Spring Boot آشنا شوید و مهارتهای لازم برای توسعهی برنامههای کاربردی مبتنی بر این فریمورک محبوب جاوا را کسب کنید.
❤4
⚖️ چرا باید equals و hashCode با هم Override شوند؟
برنامهنویسی شیءگرا در جاوا به شدت بر پایهی مقایسهی اشیاء است.
دو متد مهم که در این زمینه نقش حیاتی دارند، equals و hashCode هستند.
📌 متد equals
برای مقایسهی محتوای دو شیء استفاده میشود.
به صورت پیشفرض از کلاس Object به ارث میرسد و فقط مقایسهی آدرس حافظه انجام میدهد.
معمولاً باید آن را Override کنیم تا بتوانیم دو شیء با محتوای یکسان را برابر در نظر بگیریم.
📌 متد hashCode
این متد یک عدد صحیح (int) برمیگرداند که نشاندهندهی یک Hash برای شیء است.
در ساختارهایی مثل HashMap, HashSet و Hashtable برای سریع پیدا کردن اشیاء استفاده میشود.
قرارداد جاوا میگوید:
اگر a.equals(b) درست باشد، باید a.hashCode() == b.hashCode() هم درست باشد.
🔎 مشکل وقتی فقط equals را Override کنیم
📌 توضیح:
ما equals را Override کردیم اما hashCode را نه.
در واقع HashSet ابتدا hashCode را چک میکند تا موقعیت را پیدا کند. چون hashCode پیشفرض برای دو شیء متفاوت است، حتی اگر equals درست باشد، شیء پیدا نمیشود.
🔎 مثال درست با Override هر دو متد
📌 حالا چون هم equals و هم hashCode درست Override شدهاند، مجموعه به درستی کار میکند.
🎯 جمعبندی
equals:
محتوای اشیاء را مقایسه میکند.
hashCode:
برای جستوجوی سریع در Collectionهای مبتنی بر Hash استفاده میشود.
اگر equals را Override کردید، حتماً باید hashCode را هم Override کنید، وگرنه ساختارهایی مثل HashSet و HashMap رفتار غیرمنتظره خواهند داشت.
برنامهنویسی شیءگرا در جاوا به شدت بر پایهی مقایسهی اشیاء است.
دو متد مهم که در این زمینه نقش حیاتی دارند، equals و hashCode هستند.
📌 متد equals
برای مقایسهی محتوای دو شیء استفاده میشود.
به صورت پیشفرض از کلاس Object به ارث میرسد و فقط مقایسهی آدرس حافظه انجام میدهد.
معمولاً باید آن را Override کنیم تا بتوانیم دو شیء با محتوای یکسان را برابر در نظر بگیریم.
📌 متد hashCode
این متد یک عدد صحیح (int) برمیگرداند که نشاندهندهی یک Hash برای شیء است.
در ساختارهایی مثل HashMap, HashSet و Hashtable برای سریع پیدا کردن اشیاء استفاده میشود.
قرارداد جاوا میگوید:
اگر a.equals(b) درست باشد، باید a.hashCode() == b.hashCode() هم درست باشد.
🔎 مشکل وقتی فقط equals را Override کنیم
import java.util.HashSet;
class Person {
String name;
Person(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Person)) return false;
Person person = (Person) o;
return name.equals(person.name);
}
}
public class Test {
public static void main(String[] args) {
HashSet<Person> set = new HashSet<>();
set.add(new Person("Ali"));
System.out.println(set.contains(new Person("Ali"))); // false
}
}
📌 توضیح:
ما equals را Override کردیم اما hashCode را نه.
در واقع HashSet ابتدا hashCode را چک میکند تا موقعیت را پیدا کند. چون hashCode پیشفرض برای دو شیء متفاوت است، حتی اگر equals درست باشد، شیء پیدا نمیشود.
🔎 مثال درست با Override هر دو متد
import java.util.HashSet;
import java.util.Objects;
class Person {
String name;
Person(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Person)) return false;
Person person = (Person) o;
return name.equals(person.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}
public class Test {
publiSystem.out.println(String[] args) {
HashSet<Person> set = new HashSet<>();
set.add(new Person("Ali"));
System.out.println(set.contains(new Person("Ali"))); // true
}
}
📌 حالا چون هم equals و هم hashCode درست Override شدهاند، مجموعه به درستی کار میکند.
🎯 جمعبندی
equals:
محتوای اشیاء را مقایسه میکند.
hashCode:
برای جستوجوی سریع در Collectionهای مبتنی بر Hash استفاده میشود.
اگر equals را Override کردید، حتماً باید hashCode را هم Override کنید، وگرنه ساختارهایی مثل HashSet و HashMap رفتار غیرمنتظره خواهند داشت.
#کاربرـپیشرفته
🆔 @javapro_ir
🆔 @group_javapro
👍6❤2
⚡️ @javapro_ir✈️ @group_javapro
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🌟 قرارداد کامل
متد
قوانین متد
۱️⃣ بازتابی بودن (Reflexive): هر شیء باید با خودش برابر باشد.
۲️⃣ متقارن بودن (Symmetric): اگر
۳️⃣ گذرا بودن (Transitive): اگر
۴️⃣ سازگاری (Consistent): نتایج مقایسه باید در صورت تغییر نکردن وضعیت اشیاء ثابت بماند.
۵️⃣ عدم برابری با null: هیچ شیء نباید برابر با
قوانین متد
۱️⃣ سازگاری با equals: اگر دو شیء برابر باشند (
۲️⃣ سازگاری زمانی: تا زمانی که وضعیت شیء تغییر نکرده باشد، مقدار
۳️⃣ نامساویها ممکن است یکسان باشند: اگر دو شیء برابر نباشند، مجاز است که
مثال عملی:
در این مثال، اگر دو شیء از نوع
نتیجهگیری:
رعایت قرارداد
equals
و hashCode
در جاوامتد
equals
و hashCode
دو بخش جداییناپذیر از قرارداد برابری در جاوا هستند. زمانیکه شما این متدها را بازنویسی میکنید، باید قوانین مشخصی را رعایت کنید تا رفتار کلاسهایتان قابل پیشبینی و درست باقی بماند. این قوانین به صورت رسمی در مستندات جاوا تعریف شدهاند.قوانین متد
equals
:۱️⃣ بازتابی بودن (Reflexive): هر شیء باید با خودش برابر باشد.
obj.equals(obj) // همیشه باید true باشد
۲️⃣ متقارن بودن (Symmetric): اگر
a.equals(b)
درست باشد، باید b.equals(a)
هم درست باشد.a.equals(b) == b.equals(a)
۳️⃣ گذرا بودن (Transitive): اگر
a.equals(b)
و b.equals(c)
درست باشند، آنگاه a.equals(c)
نیز باید درست باشد.if(a.equals(b) && b.equals(c)) {
a.equals(c) == true;
}
۴️⃣ سازگاری (Consistent): نتایج مقایسه باید در صورت تغییر نکردن وضعیت اشیاء ثابت بماند.
a.equals(b) // همیشه همان نتیجه را برمیگرداند تا وقتی که وضعیت a و b تغییر نکند
۵️⃣ عدم برابری با null: هیچ شیء نباید برابر با
null
باشد.a.equals(null) // همیشه false
قوانین متد
hashCode
:۱️⃣ سازگاری با equals: اگر دو شیء برابر باشند (
equals
آنها true باشد)، مقدار hashCode
آنها باید یکی باشد.۲️⃣ سازگاری زمانی: تا زمانی که وضعیت شیء تغییر نکرده باشد، مقدار
hashCode
آن باید ثابت بماند.۳️⃣ نامساویها ممکن است یکسان باشند: اگر دو شیء برابر نباشند، مجاز است که
hashCode
یکسانی داشته باشند، ولی توصیه میشود که تا جای ممکن متفاوت باشند.مثال عملی:
import java.util.Objects;
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
در این مثال، اگر دو شیء از نوع
Person
دارای نام و سن یکسان باشند، هم equals
و هم hashCode
آنها برابر خواهد بود. این امر باعث میشود در ساختارهایی مثل HashSet
یا HashMap
رفتار درستی داشته باشند.نتیجهگیری:
رعایت قرارداد
equals
و hashCode
برای جلوگیری از خطاهای غیرمنتظره در مجموعههایی مثل HashSet
،
HashMap و دیگر ساختارهای داده وابسته به هش بسیار حیاتی است. بیتوجهی به این قوانین میتواند منجر به خطاهایی شود که پیدا کردن آنها بسیار دشوار است.#کاربرـپیشرفته
🆔 @javapro_ir
🆔 @group_javapro
👍3❤1
شرکت دادهورزی سداد به منظور توسعه تیمهای فنی خود، در حال جذب متخصصین با مهارتهای زیر میباشد:
🔹 مسلط به Java (نسخه 8 به بالا)
🔹 آشنایی با Spring Framework
🔹 تسلط بر مفاهیم OOP
🔹 تجربه کار با JPA / Hibernate
🔹 تجربه توسعه RESTful API
🔹 توانایی کار با پایگاه دادههای PostgreSQL یا DB2
🔹 آشنایی با ابزار Maven
🔹 توانایی کار با Git و Git-based workflow
📧 برای ارسال رزومه
در صورت تمایل به همکاری، رزومه خود را به آدرس پست الکترونیک زیر ارسال فرمایید:
✉️ [email protected]
⚡️ @javapro_ir✈️ @group_javapro
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
📌 مفهوم Pass by Value در جاوا
در جاوا همهی پارامترها بهصورت Pass by Value (یعنی ارسال مقدار) به متدها منتقل میشوند.
اما بسیاری از برنامهنویسان در ابتدا فکر میکنند جاوا Pass by Reference دارد، چون وقتی یک آبجکت به متد ارسال میشود، تغییر روی آن آبجکت در بیرون متد هم دیده میشود.
🔎 بیایید دقیقتر نگاه کنیم:
اگر نوعهای ابتدایی (Primitive) مثل int, double, boolean را ارسال کنید، مقدار کپی میشود. پس تغییرات داخل متد روی متغیر اصلی اثری ندارد.
اگر آبجکت را ارسال کنید، در واقع کپی آدرس آبجکت (Reference Value) ارسال میشود. بنابراین متد میتواند به همان آبجکت اشاره کرده و دادههایش را تغییر دهد. اما خود رفرنس اصلی کپی شده و تغییرش بیاثر است.
👉 نتیجه: مقدار x تغییر نکرد چون فقط کپی به متد داده شده بود.
👉 اینجا رشتهی name تغییر کرد، چون رفرنس کپی شده به همان آبجکت اشاره داشت.
📘 مثال ۳ – تغییر رفرنس داخل متد:
👉 در اینجا مقدار name تغییر نکرد چون رفرنس اصلی کپی شده بود و تغییر رفرنس داخل متد روی متغیر اصلی بیاثر است.
✅ نتیجهگیری:
جاوا همیشه Pass by Value است، حتی برای آبجکتها. فقط نکته این است که وقتی آبجکتها را پاس میدهید، در واقع کپی رفرنس پاس میشود، نه خود آبجکت. همین موضوع باعث سردرگمی خیلیها میشود.
در جاوا همهی پارامترها بهصورت Pass by Value (یعنی ارسال مقدار) به متدها منتقل میشوند.
اما بسیاری از برنامهنویسان در ابتدا فکر میکنند جاوا Pass by Reference دارد، چون وقتی یک آبجکت به متد ارسال میشود، تغییر روی آن آبجکت در بیرون متد هم دیده میشود.
🔎 بیایید دقیقتر نگاه کنیم:
اگر نوعهای ابتدایی (Primitive) مثل int, double, boolean را ارسال کنید، مقدار کپی میشود. پس تغییرات داخل متد روی متغیر اصلی اثری ندارد.
اگر آبجکت را ارسال کنید، در واقع کپی آدرس آبجکت (Reference Value) ارسال میشود. بنابراین متد میتواند به همان آبجکت اشاره کرده و دادههایش را تغییر دهد. اما خود رفرنس اصلی کپی شده و تغییرش بیاثر است.
📘 مثال ۱ – نوع Primitive:
public class PassByValueDemo {
public static void main(String[] args) {
int x = 10;
changeValue(x);
System.out.println("x after method: " + x); // خروجی: 10
}
static void changeValue(int num) {
num = 20; // فقط کپی تغییر میکند
}
}
👉 نتیجه: مقدار x تغییر نکرد چون فقط کپی به متد داده شده بود.
📘 مثال ۲ – آبجکتها:
class Person {
String name;
}
public class PassByValueDemo2 {
public static void main(String[] args) {
Person p = new Person();
p.name = "Ali";
changeName(p);
System.out.println("Person name: " + p.name); // خروجی: Reza
}
static void changeName(Person person) {
person.name = "Reza"; // دادهی داخل آبجکت تغییر میکند
}
}
👉 اینجا رشتهی name تغییر کرد، چون رفرنس کپی شده به همان آبجکت اشاره داشت.
📘 مثال ۳ – تغییر رفرنس داخل متد:
static void reassignObject(Person person) {
person = new Person();
person.name = "Sara";
}
public static void main(String[] args) {
Person p = new Person();
p.name = "Ali";
reassignObject(p);
System.out.println(p.name); // خروجی: Ali
}
👉 در اینجا مقدار name تغییر نکرد چون رفرنس اصلی کپی شده بود و تغییر رفرنس داخل متد روی متغیر اصلی بیاثر است.
✅ نتیجهگیری:
جاوا همیشه Pass by Value است، حتی برای آبجکتها. فقط نکته این است که وقتی آبجکتها را پاس میدهید، در واقع کپی رفرنس پاس میشود، نه خود آبجکت. همین موضوع باعث سردرگمی خیلیها میشود.
#کاربرـپیشرفته
🆔 @javapro_ir
🆔 @group_javapro
👍7❤1
📌موضوع: Immutable Objects در جاوا و ارتباط آن با Pass by Value
در جاوا بعضی از کلاسها Immutable هستند؛ یعنی بعد از ساخته شدن، حالت داخلی آنها دیگر تغییر نمیکند.
معروفترین نمونهی Immutable در جاوا، کلاس String است.
🔎 ویژگی اصلی Immutable این است که اگر به نظر برسد در حال تغییر دادن شیء هستیم، در واقع یک شیء جدید ساخته میشود و رفرنس متغیر به آن اشاره میکند.
📘 مثال ۱ – رشتهها (String):
👉 چرا خروجی نهایی هنوز
چون شیء رشته تغییر نکرد، بلکه یک String جدید ساخته شد و فقط رفرنس محلی (
📘 مثال ۲ – مقایسه با Mutable Object (مثل StringBuilder):
👉 این بار شیء تغییر کرد، چون StringBuilder یک کلاس Mutable است.
✅ نتیجهگیری:
* جاوا همیشه Pass by Value است، اما رفتار Immutable vs Mutable تعیین میکند که دادهها "به ظاهر" تغییر میکنند یا نه.
* در مورد Immutableها مثل String، هر تغییری منجر به ساخت یک شیء جدید میشود.
* در مورد Mutableها مثل StringBuilder یا ArrayList، تغییرات مستقیماً روی همان شیء اثر میگذارد.
در جاوا بعضی از کلاسها Immutable هستند؛ یعنی بعد از ساخته شدن، حالت داخلی آنها دیگر تغییر نمیکند.
معروفترین نمونهی Immutable در جاوا، کلاس String است.
🔎 ویژگی اصلی Immutable این است که اگر به نظر برسد در حال تغییر دادن شیء هستیم، در واقع یک شیء جدید ساخته میشود و رفرنس متغیر به آن اشاره میکند.
📘 مثال ۱ – رشتهها (String):
public class ImmutableDemo {
public static void main(String[] args) {
String s = "Ali";
changeString(s);
System.out.println("Original: " + s); // خروجی: Ali
}
static void changeString(String str) {
str = str + " Reza"; // شیء جدید ساخته میشود
System.out.println("Inside method: " + str); // خروجی: Ali Reza
}
}
👉 چرا خروجی نهایی هنوز
Ali
است؟چون شیء رشته تغییر نکرد، بلکه یک String جدید ساخته شد و فقط رفرنس محلی (
str
) در متد به آن اشاره کرد.📘 مثال ۲ – مقایسه با Mutable Object (مثل StringBuilder):
public class MutableDemo {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("Ali");
changeBuilder(sb);
System.out.println("After method: " + sb); // خروجی: Ali Reza
}
static void changeBuilder(StringBuilder builder) {
builder.append(" Reza"); // همان شیء تغییر میکند
}
}
👉 این بار شیء تغییر کرد، چون StringBuilder یک کلاس Mutable است.
✅ نتیجهگیری:
* جاوا همیشه Pass by Value است، اما رفتار Immutable vs Mutable تعیین میکند که دادهها "به ظاهر" تغییر میکنند یا نه.
* در مورد Immutableها مثل String، هر تغییری منجر به ساخت یک شیء جدید میشود.
* در مورد Mutableها مثل StringBuilder یا ArrayList، تغییرات مستقیماً روی همان شیء اثر میگذارد.
#کاربرـپیشرفته
🆔 @javapro_ir
🆔 @group_javapro
👍5❤1🗿1
📌 موضوع: String Pool در جاوا و تفاوت == با equals
در جاوا رشتهها (`String`) یک ویژگی خاص دارند به نام String Pool. این مکانیزم باعث میشود مدیریت حافظه بهینهتر شود.
🔎 String Pool چیست؟
وقتی شما یک رشته با لیترال (Literal) بسازید، جاوا آن را در یک حافظهی خاص به نام String Pool نگه میدارد. اگر دوباره همان رشته را با همان مقدار بسازید، جاوا از همان شیء موجود در String Pool استفاده میکند.
📘 مثال ۱ – استفاده از String Pool:
👉 چرا
چون هر دو متغیر به یک شیء یکسان در String Pool اشاره میکنند.
📘 مثال ۲ – استفاده از new String():
👉 این بار
اما
📘 مثال ۳ – متد intern():
👉 متد
✅ نتیجهگیری:
* همیشه از equals() برای مقایسهی مقدار رشتهها استفاده کنید.
*
* بهینهسازی حافظه در جاوا برای رشتهها به کمک String Pool انجام میشود.
در جاوا رشتهها (`String`) یک ویژگی خاص دارند به نام String Pool. این مکانیزم باعث میشود مدیریت حافظه بهینهتر شود.
🔎 String Pool چیست؟
وقتی شما یک رشته با لیترال (Literal) بسازید، جاوا آن را در یک حافظهی خاص به نام String Pool نگه میدارد. اگر دوباره همان رشته را با همان مقدار بسازید، جاوا از همان شیء موجود در String Pool استفاده میکند.
📘 مثال ۱ – استفاده از String Pool:
public class StringPoolDemo {
public static void main(String[] args) {
String s1 = "Ali";
String s2 = "Ali";
System.out.println(s1 == s2); // true
System.out.println(s1.equals(s2)); // true
}
}
👉 چرا
==
اینجا true شد؟چون هر دو متغیر به یک شیء یکسان در String Pool اشاره میکنند.
📘 مثال ۲ – استفاده از new String():
public class StringPoolDemo2 {
public static void main(String[] args) {
String s1 = new String("Ali");
String s2 = new String("Ali");
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2)); // true
}
}
👉 این بار
==
false شد، چون هر بار که از new String()
استفاده میکنیم، یک شیء جدید در حافظه Heap ساخته میشود (نه در String Pool).اما
equals()
مقدار محتوای رشته را مقایسه میکند، بنابراین true میدهد.📘 مثال ۳ – متد intern():
public class StringPoolDemo3 {
public static void main(String[] args) {
String s1 = new String("Ali");
String s2 = s1.intern(); // این رشته وارد String Pool میشود
String s3 = "Ali";
System.out.println(s2 == s3); // true
}
}
👉 متد
intern()
باعث میشود رشته وارد String Pool شود و از آن به بعد مقایسه با ==
هم true خواهد شد.✅ نتیجهگیری:
* همیشه از equals() برای مقایسهی مقدار رشتهها استفاده کنید.
*
==
فقط بررسی میکند که دو متغیر به یک شیء یکسان در حافظه اشاره میکنند.* بهینهسازی حافظه در جاوا برای رشتهها به کمک String Pool انجام میشود.
#کاربر_مبتدی
🆔 @javapro_ir
🆔 @group_javapro
❤5👍5
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
راه حلی برای اجرا کردن برنامه های روزانه ات
اگر میخوای آموزش ببینی، کتاب بخونی، ورزش کنی و... ولی اهمال کاری میکنی این راه حل مناسب شماست.
بخش اول
اگر میخوای آموزش ببینی، کتاب بخونی، ورزش کنی و... ولی اهمال کاری میکنی این راه حل مناسب شماست.
بخش اول
🆔 @javapro_ir
🆔 @group_javapro
👍4