جاواپرو | برنامه نویسی جاوا | Java
5.89K subscribers
1.15K photos
158 videos
383 files
1.3K links
🎓آکـــــــــادمی جاواپـــــــــــــــرو
آموزش پیش نیازهای برنامه نویسی
آموزش مقدماتی تا پیشرفته جاوا
آموزش Spring Boot
سفارش پروژه ، دوره و تدریس خصوصی: @rzutab
مشاهده دوره ها و ثبت نام👇
wwww.academyjavapro.com
گروه جاوا : @group_javapro
Download Telegram
📘 تفاوت StringBuilder با String.concat() و دلیل پرهیز از استفاده‌ی + در حلقه‌ها

در جاوا، رشته‌ها (`String`) Immutable (تغییرناپذیر) هستند؛ یعنی هر بار که یک عملیات ترکیب (`+` یا `concat`) انجام می‌دهی، یک شیء جدید از نوع String ساخته می‌شود و مقدار قبلی در حافظه باقی می‌ماند.

به همین خاطر، اگر در حلقه از + یا concat() استفاده کنی، در واقع در هر بار تکرار، شیء جدیدی در حافظه ایجاد می‌شود که باعث کاهش شدید Performance و افزایش مصرف حافظه می‌گردد.


🔹 ۱. مشکل استفاده از + در حلقه‌ها

📘 مثال:


public class StringConcatExample {
public static void main(String[] args) {
String result = "";
for (int i = 0; i < 5; i++) {
result = result + i;
}
System.out.println(result);
}
}


🔍 در ظاهر، خروجی ساده است:


01234


اما در پشت صحنه، در هر بار اجرای خط result = result + i;
یک StringBuilder موقت ساخته می‌شود، مقدار قبلی و جدید را به هم می‌چسباند، سپس به String تبدیل می‌شود و در نهایت شیء قبلی از بین می‌رود.

یعنی برای پنج بار تکرار، حداقل پنج شیء String و پنج شیء StringBuilder ساخته می‌شود!
در حلقه‌های بزرگ (مثلاً هزار بار)، این کار بسیار پرهزینه می‌شود.


🔹 ۲. استفاده از String.concat()

روش دیگر، استفاده از متد concat() است:


public class ConcatExample {
public static void main(String[] args) {
String result = "";
for (int i = 0; i < 5; i++) {
result = result.concat(String.valueOf(i));
}
System.out.println(result);
}
}


این هم دقیقاً همان مشکل را دارد؛ چون متد concat() هم رشته‌ی جدیدی می‌سازد.
در واقع، concat() درون خودش چیزی شبیه این انجام می‌دهد:


return new String(this.value + otherValue);


یعنی هیچ فرقی از نظر Immutable بودن با + ندارد.


🔹 ۳. راه‌حل صحیح: استفاده از StringBuilder

برای جلوگیری از ساخت رشته‌های متعدد، از StringBuilder استفاده می‌کنیم که Mutable است و مستقیماً روی همان آبجکت کار می‌کند.

📘 مثال بهینه:


public class StringBuilderExample {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 5; i++) {
sb.append(i);
}
System.out.println(sb.toString());
}
}


در اینجا فقط یک شیء StringBuilder در حافظه ساخته می‌شود و متد append() در هر بار تکرار به همان شیء اضافه می‌کند.
در پایان با toString() آن را به String تبدیل می‌کنیم.


🔹 ۴. مقایسه‌ی عملکرد

📘 مثال:


public class PerformanceTest {
public static void main(String[] args) {
long start1 = System.nanoTime();
String s = "";
for (int i = 0; i < 10000; i++) {
s += i;
}
long duration1 = System.nanoTime() - start1;

long start2 = System.nanoTime();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
sb.append(i);
}
long duration2 = System.nanoTime() - start2;

System.out.println("Using '+': " + duration1);
System.out.println("Using StringBuilder: " + duration2);
}
}


🔍 در بیشتر سیستم‌ها، تفاوت زمان می‌تواند ده‌ها برابر باشد.
استفاده از StringBuilder در حلقه‌ها معمولاً ۱۰ تا ۲۰ برابر سریع‌تر است.


🔥 نکته‌ی پایانی:
کامپایلر جاوا در صورت استفاده از + خارج از حلقه‌ها، خودش آن را به StringBuilder تبدیل می‌کند.
اما در داخل حلقه‌ها، این کار را انجام نمی‌دهد، چون هر بار باید مقدار جدید بسازد.

#کاربرـحرفهـای


🆔 @javapro_ir
🆔 @group_javapro
👍4
قصد داریم آموزش های پروژه محور معماری میکروسرویس ها با جاوا عملی و واقعی به صورت دیپلوی تهیه کنیم.
مثلا پروژه مدیریت رستوران روی دامنه و هاست واقعی و کاملا عملی
این آموزش ها تمرکزش رو اینکه شما قبلا مباحث میکروسرویس رو یاد گرفتید و حالا میخواید چند پروژه عملی انجام بدید و خودتون محک بزنید، لطفا در ادامه در نظرسنجی بعد از این پیام شرکت کنید که ببینیم چه سطح آموزشی مدنظرتون است.
👍4
در مورد آموزش های پروژه محور معماری میکروسرویس ها با جاوا نظیر مدیریت رستوران، درگاه پرداخت آنلاین، فروشگاه اینترنتی و.... میخواید در چه سطحی آموزش داده بشه
Anonymous Poll
43%
الف) در آموزش پروژه محور فرض بر این بگیریم شما مباحث رو بلد هستید و روی انجام پروژه واقعی تمرکز کنیم
57%
ب) در آموزش پروژه محور در زمان انجام پروژه مباحث هم آموزش داده شود
یه مثال می‌زنم تا منظورم روشن‌تر بشه:
فرض کنید می‌خوایم یه برنامه مدیریت رستوران رو با معماری میکروسرویس و با استفاده از Java و Spring Boot پیاده‌سازی کنیم.
حالا دو رویکرد داریم:

گزینه الف) فرض کنیم شما با مفاهیمی مثل Spring Boot، Security، Docker، Kafka و... آشنا هستید و مستقیماً بریم سراغ نحوه استفاده از این ابزارها در پروژه واقعی و روی معماری میکروسرویس تمرکز کنیم.

گزینه ب) یا این‌که پیش‌نیازها و ابزارهایی که در پروژه استفاده می‌شن رو هم از صفر آموزش بدیم تا دوره کاملاً بدون نیاز به پیش‌نیاز باشه.

بعضی از دوستان می‌گن پرداختن به پیش‌نیازها در دوره پروژه‌محور باعث طولانی و خسته‌کننده شدن آموزش میشه و بهتره مستقیم وارد پروژه واقعی بشیم.
دوره های پروژه محور معماری میکروسرویس ها با جاوا و اسپرینگ بوت نظیر مدیریت رستوران،فروشگاه اینترنتی،درگاه پرداخت آنلاین و... در چه سطحی برگزار شود؟
Anonymous Poll
67%
مخاطب سطح متوسط، تک تک اجزا باز بشه و آموزش داده شود.
33%
مخاطب سطح حرفه ای، نیاز نیست خیلی چیزا در زمان انجام پروژه عملی آموزش داده شود.
در این نظرسنجی هاشرکت کنید چون قراره ی آموزش پروژه محور مایکروسرویس- مدیریت رستوران تهیه کنیم و سطح آموزش را این نظرسنجی ها مشخص خواهد کرد.
📘 موضوع: Dependency Injection در جاوا — مفهوم و اهمیت آن در طراحی شیءگرا

در برنامه‌نویسی شیءگرا، کلاس‌ها معمولاً برای انجام کارهای خود به اشیای دیگر نیاز دارند.
به این اشیای وابسته، Dependency (وابستگی) گفته می‌شود.
اما نحوه‌ی ایجاد و مدیریت این وابستگی‌هاست که تفاوت بین کد ضعیف و کد قابل‌توسعه و تست‌پذیر را مشخص می‌کند.


🔹 ۱. مشکل: وابستگی مستقیم بین کلاس‌ها

فرض کنید کلاس Car برای کار کردن به یک Engine نیاز دارد 👇


class Engine {
void start() {
System.out.println("Engine started!");
}
}

class Car {
private Engine engine = new Engine(); // وابستگی مستقیم!

void drive() {
engine.start();
System.out.println("Car is moving!");
}
}


در نگاه اول ساده است، اما یک مشکل بزرگ دارد:
کلاس Car خودش تصمیم گرفته که چطور Engine را بسازد.
اگر روزی بخواهید نوع موتور را تغییر دهید (مثلاً از Engine به ElectricEngine)، باید کد Car را تغییر دهید
یعنی Car به Engine وابسته شده و این برخلاف اصل Open/Closed Principle از SOLID است.


🔹 ۲. راه‌حل: تزریق وابستگی (Dependency Injection)

در روش Dependency Injection، به جای اینکه کلاس خودش وابستگی را بسازد،
ما آن را از بیرون تزریق می‌کنیم (از طریق سازنده، Setter یا Interface).

📘 مثال با Constructor Injection:


class Engine {
void start() {
System.out.println("Engine started!");
}
}

class Car {
private Engine engine;

// وابستگی از بیرون تزریق می‌شود
public Car(Engine engine) {
this.engine = engine;
}

void drive() {
engine.start();
System.out.println("Car is moving!");
}
}

public class Main {
public static void main(String[] args) {
Engine engine = new Engine();
Car car = new Car(engine); // تزریق وابستگی
car.drive();
}
}


در اینجا، Car دیگر مسئول ساخت Engine نیست — فقط از آن استفاده می‌کند.
در نتیجه می‌توانیم نوع موتور را در آینده به‌راحتی تغییر دهیم، بدون دست زدن به کد Car


🔹 ۳. انواع Dependency Injection

1. Constructor Injection → تزریق از طریق سازنده (مثل مثال بالا)
2. Setter Injection → تزریق از طریق متد Setter
3. Interface Injection → وابستگی از طریق متدی در Interface تزریق می‌شود

📘 مثال Setter Injection:


class Car {
private Engine engine;

public void setEngine(Engine engine) {
this.engine = engine;
}

void drive() {
engine.start();
System.out.println("Car is moving!");
}
}



🔹 ۴. مزایای استفاده از Dependency Injection

کاهش Coupling (وابستگی مستقیم) بین کلاس‌ها
افزایش Testability (قابل تست شدن راحت‌تر)
افزایش Reusability (قابل استفاده مجدد بودن کلاس‌ها)
رعایت اصول SOLID مخصوصاً Open/Closed و Single Responsibility

📘 مثال تست راحت‌تر با DI:


class MockEngine extends Engine {
void start() {
System.out.println("Mock engine started (for testing)");
}
}

public class Test {
public static void main(String[] args) {
Car car = new Car(new MockEngine());
car.drive(); // تست بدون اجرای موتور واقعی
}
}


در اینجا، بدون تغییر در کلاس Car`، یک `MockEngine تزریق کردیم تا تست انجام شود.


🔹 ۵. Dependency Injection در فریم‌ورک‌ها (مثل Spring)

فریم‌ورک‌هایی مانند Spring این فرایند را به‌صورت خودکار انجام می‌دهند.
یعنی فقط با استفاده از Annotationهایی مانند @Component و `@Autowired
Spring خودش وابستگی‌ها را می‌سازد و تزریق می‌کند.

📘 مثال:


@Component
class Engine {
void start() {
System.out.println("Engine started!");
}
}

@Component
class Car {
private final Engine engine;

@Autowired
public Car(Engine engine) {
this.engine = engine;
}

void drive() {
engine.start();
System.out.println("Car is moving!");
}
}


در این حالت، Spring Container خودش متوجه می‌شود که Car به Engine نیاز دارد و آن را تزریق می‌کند.
👍71
جمع‌بندی نهایی:

* در واقع Dependency Injection یعنی واگذاری کنترل ساخت وابستگی‌ها به بیرون از کلاس.
* این کار باعث می‌شود کد ما منعطف‌تر، تست‌پذیرتر و تمیزتر شود.
* این مفهوم پایه‌ی اصلی فریم‌ورک‌هایی مانند Spring است و یکی از اصول مهم طراحی شیءگرا مدرن به شمار می‌رود.

#کاربرـپیشرفته


🆔 @javapro_ir
🆔 @group_javapro
8👍1
✳️ کار با JSON در جاوا — آشنایی با Jackson و Gson

در برنامه‌نویسی مدرن، JSON یکی از پرکاربردترین فرمت‌ها برای ذخیره و تبادل داده‌ها است. در جاوا، دو کتابخانه‌ی بسیار محبوب برای کار با JSON وجود دارد: Jackson و Gson. هر دو امکان تبدیل (Serialization) و برعکس‌تبدیل (Deserialization) اشیاء جاوا به JSON را فراهم می‌کنند.


🔹 ۱. کتابخانه‌ی Jackson
درواقع Jackson یکی از قدرتمندترین ابزارهای کار با JSON در جاواست که توسط FasterXML توسعه داده شده و در بسیاری از فریمورک‌ها (مثل Spring Boot) به‌صورت پیش‌فرض استفاده می‌شود.

📘 نمونه‌ی کد:

import com.fasterxml.jackson.databind.ObjectMapper;

class User {
    public String name;
    public int age;
}

public class JacksonExample {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();

        // شیء جاوا به JSON
        User user = new User();
        user.name = "Saleh";
        user.age = 25;
        String json = mapper.writeValueAsString(user);
        System.out.println("JSON: " + json);

        // JSON به شیء جاوا
        User newUser = mapper.readValue(json, User.class);
        System.out.println("Name: " + newUser.name);
    }
}


📍 خروجی:


JSON: {"name":"Saleh","age":25}
Name: Saleh


📘 ویژگی‌های مهم Jackson:

* پشتیبانی از Annotationها مثل @JsonProperty و @JsonIgnore
* پشتیبانی از Map، List، و Genericها
* کارایی بالا در پردازش داده‌های حجیم


🔹 ۲. کتابخانه‌ی Gson
کتابخانه‌ی Gson محصول شرکت Google است و به‌دلیل سادگی و حجم کم، در پروژه‌های سبک‌تر بسیار محبوب است.

📘 نمونه‌ی کد:

import com.google.gson.Gson;

class User {
    String name;
    int age;
}

public class GsonExample {
    public static void main(String[] args) {
        Gson gson = new Gson();

        // شیء جاوا به JSON
        User user = new User();
        user.name = "Saleh";
        user.age = 25;
        String json = gson.toJson(user);
        System.out.println("JSON: " + json);

        // JSON به شیء جاوا
        User newUser = gson.fromJson(json, User.class);
        System.out.println("Name: " + newUser.name);
    }
}


📍 خروجی مشابه Jackson است:


JSON: {"name":"Saleh","age":25}
Name: Saleh


📘 ویژگی‌های مهم Gson:

* پشتیبانی از انواع Collectionها
* امکان کنترل دقیق Serialization با Annotationهایی مانند @Expose
* سادگی در استفاده و پیاده‌سازی


🧠 جمع‌بندی:
اگر در پروژه‌های بزرگ و سازمانی کار می‌کنید یا از فریمورک‌هایی مثل Spring Boot استفاده می‌کنید، کتابخانه‌ی Jackson انتخاب بهتری است چون سریع‌تر، انعطاف‌پذیرتر و سازگارتر با سیستم‌های بزرگ است.
اما اگر پروژه‌ی شما سبک‌تر است یا در محیط‌هایی مثل اندروید کار می‌کنید، کتابخانه‌ی Gson به‌دلیل سادگی و سبک بودن، گزینه‌ی ایده‌آلی محسوب می‌شود.

#کاربرـحرفهـای


🆔 @javapro_ir
🆔 @group_javapro
👍61
🤝استخدام در شریف کلینیک 🚀
ما در شریف کلینیک به دنبال افراد باانگیزه و باتجربه برای موقعیت‌های زیر هستیم 👇

💻 Java (Mid / Senior)
⚙️ Laravel (Mid / Senior)
📱 Flutter (Mid / Senior)
🌐 Next.js / React (Mid / Senior)

اگر در یکی از این حوزه‌ها تجربه و علاقه دارید،
📩 رزومه‌تون رو به ایمیل زیر ارسال کنید:
[email protected]

🏃‍♂️ تمام‌وقت | حضوری
📍 محل کار: شریف کلینیک

➡️اشتراک 👍لایک 💬کامنت

⚡️ @javapro_ir
✈️@group_javapro
Please open Telegram to view this post
VIEW IN TELEGRAM
✳️ کار با JsonNode و Tree Model در Jackson — دسترسی به داده‌های JSON بدون نیاز به ساخت کلاس

در بسیاری از مواقع، ممکن است بخواهید به داده‌های داخل یک فایل یا رشته‌ی JSON دسترسی پیدا کنید بدون اینکه ابتدا کلاس جاوایی (POJO) برای آن بسازید. در این حالت، کتابخانه‌ی Jackson راهکاری قدرتمند به نام Tree Model API ارائه می‌دهد که با استفاده از کلاس `JsonNode`، امکان پیمایش و خواندن داده‌ها را به‌صورت درختی فراهم می‌کند.


🔹 ۱. مفهوم Tree Model در Jackson
در این مدل، داده‌ی JSON مانند یک درخت در نظر گرفته می‌شود که شامل گره‌ها (Nodes) است.
هر گره می‌تواند یک Object،Array، یا Value باشد.
کلاس اصلی برای کار با این مدل، `JsonNode` است که از طریق `ObjectMapper` ساخته می‌شود.


🔹 ۲. نمونه‌ی کد — خواندن و دسترسی به داده‌ها


import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonNodeExample {
public static void main(String[] args) throws Exception {
String json = """
{
"name": "Saleh",
"age": 25,
"skills": ["Java", "Spring", "Networking"],
"address": {
"city": "Tehran",
"country": "Iran"
}
}
""";

ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(json);

// دسترسی به مقادیر
String name = root.get("name").asText();
int age = root.get("age").asInt();
String firstSkill = root.get("skills").get(0).asText();
String city = root.get("address").get("city").asText();

System.out.println("Name: " + name);
System.out.println("Age: " + age);
System.out.println("First Skill: " + firstSkill);
System.out.println("City: " + city);
}
}


📍 خروجی برنامه:


Name: Saleh
Age: 25
First Skill: Java
City: Tehran



🔹 ۳. بررسی دقیق‌تر JsonNode

* متد get() برای دسترسی به یک کلید خاص در شیء JSON استفاده می‌شود.
* متد asText()`، `asInt() و سایر متدهای asType() برای تبدیل مقدار گره به نوع داده‌ی مورد نظر کاربرد دارند.
* می‌توانید با متد isArray() و isObject() نوع گره را بررسی کنید.


🔹 ۴. مثال پیشرفته‌تر — پیمایش روی آرایه‌ها


for (JsonNode skill : root.get("skills")) {
System.out.println("Skill: " + skill.asText());
}


📍 خروجی:


Skill: Java
Skill: Spring
Skill: Networking



🧠 جمع‌بندی:
استفاده از JsonNode و Tree Model در Jackson زمانی مفید است که:

* ساخت کلاس برای JSON ضروری نیست یا داده‌ها پویا هستند.
* می‌خواهید تنها بخشی از داده را بخوانید.
* نیاز دارید ساختار JSON را بررسی یا تحلیل کنید.

اگر داده‌های JSON ساختار ثابتی دارند، بهتر است از Data Binding (با کلاس‌های جاوا) استفاده کنید، اما اگر داده‌ها پویا یا ناشناخته‌اند، Tree Model بهترین گزینه است.

#کاربرـحرفهـای


🆔 @javapro_ir
🆔 @group_javapro
👍3
✳️ موضوع: Pattern Matching در switch — ویژگی قدرتمند از جاوا 17 به بعد

در نسخه‌های جدید جاوا، یکی از تغییرات مهم و زیبا، اضافه شدن Pattern Matching در عبارت‌های switch است. این ویژگی باعث می‌شود کدهای شرطی ما خواناتر، کوتاه‌تر و ایمن‌تر از نظر نوع داده (Type-Safe) شوند.


🔹 ۱. مشکل در نسخه‌های قدیمی‌تر
در نسخه‌های قدیمی جاوا، وقتی از switch استفاده می‌کردیم، فقط نوع‌های ساده مانند int, String یا enum پشتیبانی می‌شدند.
برای بررسی نوع (type) یک شیء، مجبور بودیم از instanceof استفاده کنیم و سپس آن را cast کنیم:

static String format(Object obj) {
    if (obj instanceof Integer) {
        Integer i = (Integer) obj;
        return "Integer: " + i;
    } else if (obj instanceof String) {
        String s = (String) obj;
        return "String: " + s;
    } else {
        return "Unknown Type";
    }
}


کد بالا تکراری و مستعد خطاست. جاوا 17 با اضافه کردن Pattern Matching در switch این مشکل را به شکلی ظریف و هوشمند حل کرد.


🔹 ۲. Pattern Matching در switch — نسخه‌ی جدید و تمیزتر

در نسخه‌های جدید، می‌توانیم مستقیماً نوع متغیر را در case تعریف کنیم، بدون نیاز به casting دستی:

static String format(Object obj) {
    return switch (obj) {
        case Integer i -> "Integer: " + i;
        case String s -> "String: " + s.toUpperCase();
        case null -> "Null value detected!";
        default -> "Unknown Type";
    };
}


📍 توضیح:

* در case Integer i، اگر نوع ورودی Integer باشد، به‌صورت خودکار متغیر i ساخته می‌شود.
* نیازی به instanceof یا cast دستی نیست.
* مقدار بازگشتی با فلش -> تعریف می‌شود و در یک خط قابل نوشتن است.


🔹 ۳. مثال کامل از کاربرد عملی

public class PatternMatchingSwitch {
    public static void main(String[] args) {
        System.out.println(describe(42));
        System.out.println(describe("Saleh"));
        System.out.println(describe(3.14));
        System.out.println(describe(null));
    }

    static String describe(Object obj) {
        return switch (obj) {
            case Integer i -> "Integer number: " + i;
            case String s when s.length() > 5 -> "Long String: " + s;
            case String s -> "Short String: " + s;
            case Double d -> "Double number: " + d;
            case null -> "Null value!";
            default -> "Unknown type";
        };
    }
}


📍 خروجی برنامه:
Integer number: 42
Long String: Saleh
Double number: 3.14
Null value!

🔹 ۴. ویژگی جالب – استفاده از شرط اضافی (when clause)
عبارت when در جاوا 21 به switch اضافه شد و به شما اجازه می‌دهد برای هر case شرط خاصی تعریف کنید.
در مثال بالا، case String s when s.length() > 5 فقط زمانی اجرا می‌شود که مقدار obj رشته‌ای و طول آن بیشتر از ۵ کاراکتر باشد.


🔹 ۵. مزایای Pattern Matching در switch

* حذف کدهای تکراری و نیاز به cast دستی
* افزایش ایمنی نوع داده‌ها (Type Safety)
* افزایش خوانایی و سادگی کد
* امکان ترکیب شرط‌ها با when برای کنترل دقیق‌تر


🧠 جمع‌بندی:
ویژگی Pattern Matching در switch یکی از گام‌های بزرگ جاوا به سمت کدنویسی تابعی‌تر و خواناتر است.
این قابلیت نه‌تنها از نظر ظاهری زیباتر است، بلکه خطاهای احتمالی ناشی از تبدیل نوع را نیز کاهش می‌دهد.

#کاربرـحرفهـای


🆔 @javapro_ir
🆔 @group_javapro
👍91
🎓 موضوع: Generics در جاوا — حذف Type Casting و افزایش ایمنی نوع داده‌ها

در زبان Java، ویژگی Generics از نسخه‌ی 5 معرفی شد تا بتوانیم نوع داده (Type) را به‌صورت پارامتری تعریف کنیم. هدف اصلی Generics، افزایش ایمنی نوع (Type Safety) و حذف نیاز به Type Casting دستی است.

به‌عنوان مثال:

List<String> names = new ArrayList<>();
names.add("Saleh");
String first = names.get(0); // نیازی به Cast نیست


در نسخه‌های قدیمی‌تر:

List names = new ArrayList();
names.add("Saleh");
String first = (String) names.get(0); // نیاز به Cast



🔹 Type Parameters

نوع پارامترها معمولاً با حروف زیر نمایش داده می‌شوند:

* T → Type (نوع عمومی)
* E → Element (در Collectionها)
* K, V → Key و Value (در Mapها)
* ? → Wildcard (نوع نامشخص)

مثلاً:

class Box<T> {
    private T value;
    public void set(T value) { this.value = value; }
    public T get() { return value; }
}



🔹 Wildcards (?)

در واقع Wildcards به ما اجازه می‌دهند با انواع نامشخص کار کنیم.
مثلاً:

List<?> list = new ArrayList<String>();


اما در این حالت فقط می‌توانیم بخوانیم، نه بنویسیم (به جز مقدار null).


🔹 تفاوت بین List<?> و List<Object>

* List<?> یعنی لیستی از هر نوع (unknown type).
  🔸 نمی‌توان در آن مقدار جدید اضافه کرد (به‌جز null).
* List<Object> یعنی لیستی که *حتماً* از نوع Object است.
  🔸 می‌توان هر شیء‌ای در آن قرار داد (String، Integer، و ...).

بنابراین List<?> و List<Object> با هم یکسان نیستند.


جمع‌بندی

کلاس Generics در جاوا باعث می‌شود:

1. کد تمیزتر و امن‌تر باشد 🧩
2. از خطاهای زمان اجرا جلوگیری شود 💡
3. نیازی به Type Casting نباشد 🔒

#کاربرـپیشرفته



🆔 @javapro_ir
🆔 @group_javapro
👍73
💻دوره جامع نخبگان معماری میکروسرویس ها با Java و Spring Boot بروزرسانی شد

فصل ۲۱ به دوره اضاف شد
📅تاریخ آخرین بروزرسانی:  ۱ آبان ۱۴٠۴

🔺مشاهده


🧮امکان تهیه دوره میکروسرویس طی ۴ قسط برای مدت محدود، جهت خرید به صورت اقساط به آی دی زیر پیام بدید👇
@rzutab
Please open Telegram to view this post
VIEW IN TELEGRAM
1
🎓موضوع: Bounded Generics در جاوا — محدودسازی نوع پارامترها با `extends` و `super`

در ادامه‌ی مبحث Generics، حالا به یکی از ویژگی‌های مهم آن می‌رسیم:
مبحث Bounded Type Parameters
این ویژگی به ما اجازه می‌دهد نوع پارامتر Generic را محدود کنیم تا فقط از نوع خاصی (یا زیرکلاس آن) استفاده شود.


🔹 Upper Bound (`extends`)

وقتی از extends استفاده می‌کنیم، یعنی نوع پارامتر باید از یک کلاس خاص ارث‌بری کند یا یک اینترفیس خاص را پیاده‌سازی کرده باشد.

مثلاً:


class Box<T extends Number> {
private T value;
public void set(T value) { this.value = value; }
public T get() { return value; }
}


حالا فقط کلاس‌هایی مثل Integer, Double, Float و سایر زیرکلاس‌های Number مجاز هستند:


Box<Integer> intBox = new Box<>();
Box<Double> doubleBox = new Box<>();
// Box<String> stringBox خطا: String زیرکلاس Number نیست



🔹 Lower Bound (`super`)

وقتی از super در Wildcard استفاده می‌کنیم، یعنی نوع پارامتر باید ابرکلاس (Superclass) نوع مشخص‌شده باشد.
این روش معمولاً هنگام نوشتن داده‌ها در Collection به‌کار می‌رود.

مثلاً:


List<? super Integer> list = new ArrayList<Number>();
list.add(10); // مجاز
list.add(20); // مجاز


اما هنگام خواندن از لیست، نوع بازگشتی فقط به صورت Object شناخته می‌شود.


🔹 نکته کاربردی: PECS اصل معروف در Generics

PECS = Producer Extends, Consumer Super

* اگر فقط از مجموعه می‌خوانی (Producer) ➤ از extends استفاده کن
* اگر فقط در مجموعه می‌نویسی (Consumer) ➤ از super استفاده کن


جمع‌بندی

درواقع Bounded Generics به ما کمک می‌کند:

1. از نوع‌های نامعتبر جلوگیری کنیم 🧩
2. انعطاف‌پذیری و ایمنی نوع‌ها را افزایش دهیم 🔒
3. کد قابل‌خواندن‌تر و قابل‌اعتمادتر بنویسیم 💡

#کاربرـپیشرفته


🆔 @javapro_ir
🆔 @group_javapro
👍5
🎓 متدهای Generic و Type Inference در جاوا — قدرت واقعی Generics در عمل

در پیام های قبل با مفاهیم پایه و Bounded Generics آشنا شدیم. حالا نوبت می‌رسه به بخش بسیار کاربردی این مبحث:
Generic Methods و Type Inference (تشخیص خودکار نوع داده)


🔹 متد Generic چیست؟

در جاوا، می‌توان خودِ متد را Generic تعریف کرد؛ یعنی متد نوع داده‌ی ورودی و خروجی را در زمان فراخوانی مشخص می‌کند، نه هنگام تعریف کلاس.

ساختار کلی:


public <T> void printItem(T item) {
System.out.println(item);
}


🔍 در اینجا <T> قبل از نوع بازگشتی (`void`) آمده، و نشان می‌دهد متد از نوع عمومی (Generic) است.

مثلاً:


printItem("Hello Java!"); // نوع T → String
printItem(42); // نوع T → Integer



🔹 متد Generic با نوع بازگشتی

می‌توانیم نوع بازگشتی را نیز به‌صورت Generic تعیین کنیم:


public static <T> T getFirst(List<T> list) {
return list.get(0);
}


هنگام فراخوانی، نوع T به‌صورت خودکار از روی نوع آرگومان تشخیص داده می‌شود (Type Inference):


List<String> names = List.of("Ali", "Reza");
String first = getFirst(names); // نوع T → String



🔹 Type Inference (تشخیص خودکار نوع)

جاوا معمولاً می‌تواند نوع پارامتر Generic را خودش تشخیص دهد، اما در مواقعی می‌توان آن را به‌صورت صریح هم مشخص کرد:


Integer num = GenericUtils.<Integer>getFirst(List.of(1, 2, 3));


در اینجا ما نوع T را به‌صورت دستی Integer تعیین کردیم.


🔹 نکته کاربردی

متدهای Generic معمولاً در کلاس‌های Utility و کتابخانه‌های عمومی (مثل Collections و Streams) استفاده می‌شوند تا کدها قابل‌استفاده مجدد و ایمن از نظر نوع داده باشند.
برای مثال متد Collections.<T>emptyList() نمونه‌ای از همین مفهوم است.


جمع‌بندی

* متدهای Generic اجازه می‌دهند نوع داده در زمان فراخوانی تعیین شود 🧩
* و Type Inference باعث سادگی و خوانایی کد می‌شود 👀
* این مفاهیم پایه‌ای‌ترین اصول در طراحی APIهای مدرن جاوا هستند 💡

#کاربرـپیشرفته


🆔 @javapro_ir
🆔 @group_javapro
👍52
🇮🇷🇮🇷🇮🇷🇮🇷🇮🇷 🎓لیست مهارت های مورد نیاز برای شروع برنامه نویسی و بازارکار جاوا... 🏠

🚀 دوره پرتاب | آموزش پیش نیازهای برنامه نویسی

👩‍💻دوره مقدماتی جاوا

👑 دوره شاهکار پیشرفته جاوا

👩‍💻 دوره طلایی Spring Core

👩‍💻 دوره فریمورک Spring Boot

👩‍💻دوره پروژه محور Spring Boot-سیستم دانشگاه

🛡دوره دژبان Spring Security

👑دوره جامع نخبگان میکروسرویس با Java و Spring Boot

📞پشتیبانی ثبت نام در دوره ها:
✈️@rzutab
Please open Telegram to view this post
VIEW IN TELEGRAM
جاواپرو | برنامه نویسی جاوا | Java pinned «🇮🇷🇮🇷🇮🇷🇮🇷🇮🇷 🎓لیست مهارت های مورد نیاز برای شروع برنامه نویسی و بازارکار جاوا... 🏠 🚀 دوره پرتاب | آموزش پیش نیازهای برنامه نویسی 👩‍💻دوره مقدماتی جاوا 👑 دوره شاهکار پیشرفته جاوا 👩‍💻 دوره طلایی Spring Core 👩‍💻 دوره فریمورک Spring Boot 👩‍💻دوره پروژه محور…»
🎓 تفاوت بین Stack و Heap در حافظه جاوا

در زبان جاوا، حافظه‌ی برنامه به دو بخش اصلی تقسیم می‌شود: Stack Memory و Heap Memory. درک تفاوت این دو بخش برای نوشتن برنامه‌های بهینه، جلوگیری از خطاهای حافظه و فهم رفتار اشیاء در زمان اجرا بسیار مهم است.


🧠 ۱. Stack Memory چیست؟

حافظه‌ی Stack مخصوص ذخیره‌ی متغیرهای محلی (Local Variables)**، **ارجاع‌های متدها و فریم‌های فراخوانی (Call Frames) است.
هر بار که یک متد در جاوا فراخوانی می‌شود، یک Stack Frame جدید برای آن ایجاد می‌شود که شامل پارامترهای ورودی و متغیرهای محلی همان متد است.

هنگامی که متد تمام می‌شود، Stack Frame مربوطه به‌صورت خودکار حذف می‌شود. این کار باعث می‌شود مدیریت حافظه در Stack بسیار سریع و کارآمد باشد.

📌 ویژگی‌ها:

* حافظه‌ی کوچک‌تر و سریع‌تر از Heap
* مدیریت خودکار (بدون نیاز به Garbage Collector)
* فقط داده‌های موقتی در آن نگهداری می‌شوند

📍 مثال:


public class StackExample {
public static void main(String[] args) {
int x = 10; // در Stack ذخیره می‌شود
int y = 20; // در Stack ذخیره می‌شود
int sum = add(x, y);
System.out.println(sum);
}

static int add(int a, int b) {
int result = a + b; // در Stack ذخیره می‌شود
return result;
}
}


در این مثال، هنگام فراخوانی متد add()`، یک Stack Frame جدید ایجاد می‌شود و متغیرهای `a, b, و result در آن ذخیره می‌شوند.
وقتی متد تمام می‌شود، تمام داده‌های داخل آن Frame از بین می‌روند.


💾 ۲. Heap Memory چیست؟

حافظه‌ی Heap برای نگهداری اشیاء (Objects) و مقادیر ساخته‌شده با new استفاده می‌شود.
هر چیزی که با کلیدواژه‌ی new ساخته شود، در Heap قرار می‌گیرد و ارجاع آن در Stack نگهداری می‌شود.

حافظه‌ی Heap توسط Garbage Collector مدیریت می‌شود. این به آن معناست که وقتی دیگر هیچ ارجاعی به یک شیء وجود نداشته باشد، جاوا آن را به‌صورت خودکار آزاد می‌کند.

📌 ویژگی‌ها:

* حافظه‌ی بزرگ‌تر ولی کندتر از Stack
* داده‌ها تا زمانی که به آن‌ها ارجاع وجود دارد، باقی می‌مانند
* مدیریت توسط Garbage Collector

📍 مثال:


public class HeapExample {
public static void main(String[] args) {
Person p1 = new Person("Saleh"); // شیء در Heap
Person p2 = new Person("Ali"); // شیء دیگر در Heap
p1.sayHello();
}
}

class Person {
String name;
Person(String name) {
this.name = name; // فیلد name در Heap ذخیره می‌شود
}

void sayHello() {
System.out.println("Hello, " + name);
}
}


در این مثال، اشیاء Person در حافظه‌ی Heap ذخیره می‌شوند، در حالی که ارجاع‌های p1 و p2 در Stack قرار دارند.
وقتی متد main() به پایان می‌رسد، ارجاع‌ها از بین می‌روند و در نتیجه اشیاء مربوطه در Heap توسط Garbage Collector حذف می‌شوند.


⚙️ نتیجه‌گیری:

*در واقع Stack برای داده‌های موقتی، متغیرهای محلی و فراخوانی متدهاست.
Heap برای اشیاء و داده‌هایی است که در زمان اجرا با new ایجاد می‌شوند.
* سرعت Stack بالاتر است، اما ظرفیت آن کمتر است.
* مدیریت Stack خودکار است، ولی Heap توسط Garbage Collector کنترل می‌شود.


نکته پایانی:
درک تفاوت Stack و Heap به شما کمک می‌کند خطاهایی مانند OutOfMemoryError یا StackOverflowError را بهتر درک و رفع کنید، و طراحی بهینه‌تری برای کلاس‌ها و متدها داشته باشید.

#کاربر_مبتدی


🆔 @javapro_ir
🆔 @group_javapro
👍8💯2
🎓 تفاوت بین Primitive Types و Reference Types در جاوا

در زبان جاوا، تمام متغیرها به دو دسته‌ی اصلی تقسیم می‌شوند:
Primitive Types (انواع پایه‌ای) و Reference Types (انواع ارجاعی).
درک تفاوت این دو نوع داده، برای جلوگیری از خطاهای مفهومی و نوشتن کدهای قابل اعتماد ضروری است.


🧩 ۱. Primitive Types — داده‌های پایه‌ای و ساده

در جاوا، Primitive Types مستقیماً مقدار خود را در حافظه ذخیره می‌کنند و به هیچ شیء یا ارجاعی وابسته نیستند.
این نوع داده‌ها به‌صورت ثابت و سریع عمل می‌کنند، چون در Stack Memory نگهداری می‌شوند.

📌 هشت نوع Primitive Type در جاوا وجود دارد:
byte, short, int, long, float, double, char, boolean

📍 مثال:

int a = 10;
int b = a;
b = 20;

System.out.println(a); // 10
System.out.println(b); // 20


در این مثال، مقدار a در حافظه Stack ذخیره شده و وقتی مقدار آن به b داده می‌شود، کپی می‌شود نه ارجاع.
در نتیجه تغییر مقدار b هیچ اثری روی a ندارد.


🏗️ ۲. Reference Types — ارجاع به اشیاء در حافظه Heap

هر داده‌ای که از نوع Primitive نباشد، یک Reference Type محسوب می‌شود.
به‌جای نگهداری مقدار مستقیم، در این نوع متغیرها آدرس (Reference) شیء در حافظه‌ی Heap ذخیره می‌شود.

📍 مثال:

class Person {
String name;
Person(String name) {
this.name = name;
}
}

public class ReferenceExample {
public static void main(String[] args) {
Person p1 = new Person("Saleh");
Person p2 = p1; // هر دو به یک شیء اشاره می‌کنند
p2.name = "Ali";

System.out.println(p1.name); // Ali
System.out.println(p2.name); // Ali
}
}


در این مثال، متغیرهای p1 و p2 هر دو به همان شیء در Heap اشاره می‌کنند.
بنابراین تغییر در p2 باعث تغییر در p1 نیز می‌شود، چون هر دو یک آدرس مشترک دارند.


🧠 ۳. تفاوت مفهومی بین Primitive و Reference Types

* Primitive Types: مقدار را مستقیماً در خود ذخیره می‌کنند.
* Reference Types: فقط آدرس شیء را در خود نگه می‌دارند.
* Primitive Types در Stack ذخیره می‌شوند، در حالی که Reference Types معمولاً در Heap قرار دارند.
* هنگام مقایسه با ==، در Primitive مقدار مقایسه می‌شود، ولی در Reference آدرس حافظه بررسی می‌شود.

📍 نمونه تفاوت مقایسه:

int x = 5;
int y = 5;
System.out.println(x == y); // true → مقدارها برابرند

String s1 = new String("Hello");
String s2 = new String("Hello");
System.out.println(s1 == s2); // false → آدرس‌ها متفاوت‌اند
System.out.println(s1.equals(s2)); // true → محتوا برابر است



⚙️ ۴. نکته‌ی مهم درباره‌ی Wrapper Classes

جاوا برای هر نوع Primitive یک کلاس Wrapper در پکیج java.lang دارد (مثل Integer, Double, Boolean و ...).
این کلاس‌ها Reference Type هستند اما رفتارشان تا حد زیادی شبیه Primitive است.

📍 مثال:

int num1 = 100;
Integer num2 = 100; // Auto-boxing از int به Integer

System.out.println(num1 == num2); // true → به‌خاطر unboxing خودکار



جمع‌بندی:

* Primitive Types ساده، سریع و کم‌حافظه هستند.
* Reference Types پیچیده‌ترند و برای اشیاء استفاده می‌شوند.
* تفاوت در نحوه‌ی نگهداری داده، مقایسه، و رفتار در متدها باعث تفاوت بنیادی در عملکرد این دو نوع داده می‌شود.
* درک درست این تفاوت از خطاهایی مانند NullPointerException و Unexpected Mutations جلوگیری می‌کند.


📘 نکته پایانی:
در جاوا همه‌چیز شیء نیست — انواع پایه‌ای (int, double, boolean و غیره) استثنا هستند.
اما وقتی وارد ساختارهای داده‌ای مثل List<Integer> یا Map<String, Object> می‌شویم، جاوا از Wrapper Classes برای تبدیل خودکار آن‌ها به Reference Types استفاده می‌کند (این فرایند را *Auto-boxing* می‌گویند).

#کاربر_مبتدی


🆔 @javapro_ir
🆔 @group_javapro
👍51
امروز یک آگهی استخدام در جاوا رو دیدم و گفتم برداشتم رو از این فرصت شغلی جاوا باهاتون به اشتراک بذارم.

❇️ Junior Java Developer:

تسلط بر مفاهیم پایه جاوا و OOP

آشنایی با Spring Boot و SQL

آشنایی با Git و Clean Code


❇️ Mid-Level Java Developer:

✳️تسلط بر Spring Boot، Hibernate، و Concurrency

✳️آشنایی با Spring Security و Docker

✳️درک مفاهیم دیتابیس و Performance


❇️ Senior Java Developer:

✳️تجربه معماری سیستم و Microservices

✳️تسلط بر Kafka، Elasticsearch، OAuth 2.0

✳️درک عملکرد، مقیاس‌پذیری و طراحی سیستم‌های Enterprise

📌 حالا وقت سرمایه‌گذاری روی مهارت‌هاته:
یادگیری اصولی Java + Spring Boot + Microservices
یعنی گام گذاشتن در مسیر توسعه‌دهنده‌های حرفه‌ای با درآمدهای بالا و جایگاه واقعی در تیم‌های نرم‌افزاری.

جاوا فقط یک زبان نیست؛
💬 جاوا یعنی ساختن سیستم‌هایی که دنیا رویش می‌چرخه....

💻 مسیرت رو از امروز بساز...
روی مهارتت سرمایه‌گذاری کن، نه فقط برای استخدام،
بلکه برای اینکه «در هر شرایطی، خواستنی باشی».

#جاوا #Java #استخدام #برنامه_نویسی #SpringBoot #Microservices #فرصت_شغلی #JavaDeveloper




🆔 @javapro_ir
🆔 @group_javapro
👍3🫡1