فهرست

فصل 1) Introduce 3

1.1) مروری بر تعاریف 3

1.2) برخی توضیحات 4

1.3) مروری بر نسخه‌های جاوا 5

1.4) Hello world 5

فصل 2) دستورات، کلمات کلیدی 6

2.1) دستورات چاپ 6

2.2) دستورات شرطی 6

2.2.1)حالت اول 6

2.2.2)حالت دوم 6

2.3) حلقه‌ها 6

2.3.1)حلقه با استفاده از For 6

2.3.2)حلقه با استفاده از do while 7

2.3.3)حلقه با استفاده از while 7

2.4) jar-file 7

فصل 3) ویژگی‌های کاربردی 8

3.1) استاتیک (Static) 8

3.1.1)مفهوم Singleton در الگوهای طراحی Design Pattern 9

3.2) final 10

3.2.1)متغیر ثابت(Final) 10

3.2.2)کلاس final 11

3.2.3)متد final 11

3.3) وراثت(Inheritance) 12

3.4) Abstract (مفهوم انتزاعی) 15

3.4.1)متد انتزاعی 15

3.4.2)کلاس انتزاعی 16

3.5) interface (واسط) 17

3.6) Package 19

3.7) Mutable Object یا اشیاء تغییر پذیر 19

3.8) Immutable Object یا اشیاء تغییر ناپذیر 19

3.9) Enumeration 20

3.10) Iterator 20

3.10.1)متد Iterator 21

فصل 4) متدهای مهم 24

4.1) Constructor 24

4.2) Destructor 25

4.3) متد finalize 26

4.4) متدToString 26

4.5) متد Equals 27

4.6) متدهای کلاس Object 29

4.7) متد getClass 29

4.8) Hash 29

4.8.1)تکنیک Hash 29

4.8.2)متدHashCode 30

4.9) واسط Comparable 30

4.9.1)متد compareTo 30

فصل 5) سطوح دسترسی 33

5.1) سطح دسترسیAccess Modifier یا Access Specifier 33

5.1.1)Public 33

5.1.2)private 33

5.1.3)Protected 33

5.1.4)Package Access 34

فصل 6) Java Virtual Machine (JVM) 35

6.1) Heap 35

6.1.1)Garbage Collection 35

6.1.2)تعیین فضای حافظه 35

6.2) Stack 36

6.3) ClassPath 36

6.4) MetaSpace و PermGen(Permanent Generation) 37

فصل 7) مدیریت خطا (Exception) 38

7.1) ایجاد کلاس Custom از یک اکسپشن 39

7.2) stack trace 41

7.3) finaly 42

7.4) کلاس throwable 42

7.5) استثناهای چک شده(CheckedException) 43

7.6) استثناهای چک نشده(UnCheckedException) 43

7.7) استثناء و ارث‌بری 43

فصل 8) Collections 45

8.1) ArrayList 45

8.1.1) تبدیل آرایه به ArrayList 47

8.1.2)تبدیل ArrayList به آرایه: 47

8.1.3)تبدیل Collection به آرایه 47

8.1.3.1)روش اول 47

8.1.3.2)روش دوم 47

8.2) لیست پیوندی(LinkedList) 48

8.3) مجموعه یا Set [HashSet] 49

8.3.1)تفاوت اصلی set و List 50

8.3.2)برتری مجموعه یا لیست 50

8.4) Map 50

8.4.1)نگاهی به واسط Map 51

8.4.2)put 51

8.5) کلاس‌های Arrays و Collections 52

8.5.1)برای کاربرد Arrays 52

8.5.2)مثال برای کاربرد Collections 53

8.6) مرور برخی واسط‌ها و کلاس‌های مهم دیگر 53

8.6.1)اشاره به برخی مفاهیم 54

فصل 9) فایل 55

9.1) stream 55

9.2) بستن منبع 56

9.3) کلاس FileReader 57

9.4) کلاس FileWriter 57

9.5) کلاس FileInputStream 58

9.6) کلاس FileOutputStream 58

9.7) کلاس File 58

9.8) کلاس RandomAccessFile 59

9.9) کلاس Scanner 60

9.10) کلاس Formatter 60

9.11) کلاس‌های Closeable 61

9.12) برنامه نویسی شبکه 61

9.12.1)کلاس Socket 61

9.12.2)کلاس ServerSocket 62

9.12.3)نکات 63

9.13) مفهوم Serialization 63

9.13.1)اشیاء Serializable 64

9.14) برخی کلاس‌های مهم java.io 65

9.15) الگوی طراحی Decorator در کلاس‌های java.io 65

9.16) امکانات NIO و NIO.2 66

9.17) کلاس Paths و واسط Path 66

9.18) کلاس java.nio.file.Files 66

9.19) امکان try-with-resources 67

9.20) خطاهای مربوط به کار بافایل 67

9.20.1)خطای IOException 67

9.21) مرور و موارد تکیمیلی 68



فصل 1) Introduce

1.1) مروری بر تعاریف

Java SE سرنام Java Standard Edition می‌باشد.

Java EE سرنام Java Enterprise Edition می‌باشد.

Java ME یا JME سرنام Java Micro Edition می‌باشد که زبانی محدود و کوچکتر شد حتی از Java Core می‌باشد و برای استفاده جاوا در دستگاه‌های الکترونیکی کاربرد دارد.

JRE سرنام Java Runtime Environment می‌باشد



JDK یا Java Development Kit ، نرم افزاری است که به کاربر اجازه اجرا و کامپایل برنامه‌های جاوا را می‌دهد. (بدرد برنامه نویسان جاوا میخوره)

JRE : بخش کوچکی از JDK که فقط برای اجرای یک برنامه جاوا احتیاج است و شامل موارد موجود در jdk نیست



1.2) برخی توضیحات

نکته: ترتیب اجرای برنامه به شرح زیر است:

[Fortran, C ,Pascal] > High Level Language > Assembly Language > Machine Language > hardware



نکته: زبان جاوا برای اجرا بصورت زیر عمل می‌نماید:

JVM > Byte Code(.class) < Javac compiler < Java Code(.Java) < User Interface

نکته: برنامه هایی نظیر Scala و groovy برای ران شدن نیاز به وجود JVM دارند

نکته: در جاوا به حروف بزرک و کوچک حساس هست case sensitive names

نکته: متغیر نوع int عددی بین منفی ۲ به توان 31 تا یک عدد کمتر از مثبت ۲ به توان ۳۱ میتواند بپذیرد

نکته: اعداد صحیح - کوچک از نوع short - اگر خیلی کوچک از نوع byte و اعداد بزرگ را از نوع long

نکته: اگر عدد از نوع double باشد برای اینکه تصریح کنیم که عدد از نوع double است می‌توانیم در انتهای عدد یک علامت d بگذاریم

d=4763.129837D

نکته: اگر عدد از نوع float باشد برای اینکه تصریح کنیم که عدد از نوع float است میتوانیم در انتهای عدد یک علامت f بگذاریم

f=4763.129837F

نکته: اگر عدد از نوع Long باشد برای اینکه تصریح کنیم که عدد از نوع Long است میتوانیم در انتهای عدد یک علامت l بگذاریم

l=4763.129837L

نکته: عبارت زیر یعنی اول مقدار a که ۱۲ هست را به ۱۱ تغییر بده و بعد آن را به b وارد کن

int a=12;

b=--a

نکته: عبارت زیر یعنی اول مقدار a را که ۱۲ هست به b وارد کن و بعد از این عدد ۱۲ یکی کم کن

int a=12

b=a--

برای تعریف آرایه از روش زیر استفاده می‌نماییم:

int[] array = new int[10];

or

int array[] = new int[10];

char[] array = {‘a’ , ‘s’ , ‘t’ };

نکته: در جاوا وقتی از /** استفاده نماییم یعنی داکیومنت کنونی به جاواداک ارتباط دارد

نکته: در جاوا بسته ها را با حروف کوچک و کلاس را با حالت CamelCase یعنی با حروف بزرگ شروع شود و برای متدها حرف کوچک شروع شود و با حالت CamelCase ادامه یابد و برای نامگذاری متد ها از حرف اول کوچک و ادامه با الگوی کوهان شتر استفاده شود و اگر متغیر یک Constant یا finalVariable هست همه حروف این متغیر را بزرگ تعریف نمایید و اگر در این متغیر چندین کلمه هست در این صورت بین کلمات از آندرلاین استفاده شود.

نکته: بصورت کلی پیشنهاد می‌شود که در نامگذاری‌ها از فعل استفاده نشود.

نکته:برای اینکه بدانیم یک متغیر در کجاها در workspace استفاده شده است می‌توانیم روی محل تعریف یک متغیر راست کلیک کرده و از گزینه‌های موجود references را باز کرده و از زیرمنوی workspace استفاده نماییم.

نکته: برای رفتن به مکان تعریف یک متغیر یا کلاس یا متد یا غیره از کلید F3 استفاده می‌شو د



1.3) مروری بر نسخه‌های جاوا

JDK Alpha and Beta (1995)

JDK 1.0 (January 21, 1996)

JDK 1.1 (February 19, 1997)

J2SE 1.2 (December 8, 1998)=Java2StandardEditiom

J2SE 1.3 (May 8, 2000)

J2SE 1.4 (February 6, 2002)

Java SE 5.0 (September 30, 2004)

Java SE 6 (December 11, 2006)

Java SE 7 (July 28, 2011)

Java SE 8 (March 18, 2014)

J2SE: یعنی نسخه دوم از جاوای Standard Edition

J2ME: یعنی نسخه دوم از جاوای Micro Edition

J2EE: یعنی نسخه دوم از جاوای Enterprize Edition



1.4) Hello world

برای نوشتن یک برنامه ساده به روش زیر عمل نمایید:

vim First.java

Public class First {

public static void main(String[] args) {

System.out.println("اولین برنامه !!!")

}

}

برای کامپایل کردن یک برنامه جاوای نوشته شده از دستور زیر استفاده میشود:

javac First.java

در این صورت اگر برنامه به درستی نوشته شده باشه فایل کامپایل شده اون بصورت First. Class ساخته می‌شود.در این صورت باید با دستور زیر برنامه رو اجرا کرد:

java First

نکته: اسم کلاس باید دقیقا با اسم فایل منطبق باشد

فصل 2) دستورات، کلمات کلیدی

2.1) دستورات چاپ

دستورات زیر برای چاپ در کنسول هست:

System.out.println(a);

System.out.print(X);

System.out.println(a*6+1);



2.2) دستورات شرطی

2.2.1)حالت اول

اگر شرط درست باشد مقدار value_true اجرا شود و اگر نبود مقدار value_false به اجرا در بیاید

TYPE value = CONDITION ? value_true : value_false;

عبارت زیر یعنی:یعنی اگر مقدار area از ۱۰ بزرگتر بود مقدار value برابر بشود با 1 وگرنه مقدار آن بشود منفی یک

area=5;

int value = area > 10 ? 1 :-1;



2.2.2)حالت دوم

عبارت زیر معادل عبارت استفاده شده در بالا است:

if (area>10)

value =1;

else

value = -1;

2.3) حلقه‌ها

2.3.1)حلقه با استفاده از For

شکل ایجاد حلقه با استفاده از For به صورت زیر است:

for (Yek Amaliyat ; yek shart ; yek Amaliyat){دستورات

for (int i=1;i<=10;i++){}

روش دیگر استفاده از حلقه For:

for(String s : array)

System.out.println(s);







2.3.2)حلقه با استفاده از do while

long counter=0;

do{

counter++;

System.out.println(counter);

}while(counter<10);



2.3.3)حلقه با استفاده از while

long counter=1;

while(counter<10)

{

System.out.println(counter);

counter++;

}



2.4) jar-file

برای ایجاد فایل jar میتوان از دستور زیر استفاده کرد:

jar cf jar-file input-files

که در آن:jar-file نام فایل جزی که میخواهیم ایجاد کنیم و input-file مجموعه برنامه‌های که قراره در فایل جر ما ریخته بشوند.

همچنین ابزارهایی نظیر Eclipse و Ant و Maven نیز میتوانند این کار را انجام دهند





فصل 3) ویژگی‌های کاربردی



3.1) استاتیک (Static)

  1. یک متغیر استاتیک، درواقع یک ویژگی برای یک کلاس هست و نه برای اشیاء

  2. در بین تمام اشیاء آن کلاس مشترک است.

  3. فقط یک خانه در حافظه دارد

  4. بدون ساختن شیء می‌توانیم از متغیرهای استاتیک استفاده نماییم(با کمک اسم کلاس)

  5. یک ویژگی غیر استاتیک، به ازای هر شیء یک خانه در حافظه ایجاد میکند.

  6. متدهای استاتیک نیز می‌توانیم تعریف نماییم.

  7. درحالت عادی هر متد روی یک شیء فراخوانی می‌شود اما برخی از متدها به هیچ شیء خاصی از کلاس مرتبط نیستند.(چنین متدهایی بدون ساخت هیچ شیءی باید قابل استفاده و فرخوانی باشند)

pride.setLength(393);

int max = Person.getMaxAge();

double eight = Math.pow(2,3);

String s = String.valueOf(12);

Public static void main(String[] args)

  1. متدهایی که قرار هست برای یک کلاس فراخوانی شوند و نه روی شیء خاص متدهای استاتیک هستند.

  2. متدهای استاتیک در‌واقع عملیات (رفتارهای) کلاس هستند و نه رفتارهای شیء و بر روی یک شیء فراخوانی نمی‌شوند

  3. متدهای استاتیک به شیء خاصی دسترسی ندارند(پس به ویژگی‌های اشیاء آن کلاس دسترسی ندارند)

  4. متدهای استاتیک فقط میتوانند از ویژگی‌های استاتیک استفاده نمایند اما متدهای معمولی می‌توانند از همه ویژگی‌ها استفاده نمایند(چه استاتیک و چه غیر استاتیک)

  5. متغیرهای استاتیک هم مثل ویژگی‌های معمولی باید مقداردهی اولیه شوند تا مقادیر و حالت اولیه معتبری داشته باشند-اما نکته اینجاست که آماده سازی اشیاء به ازای هر شیء جدید باید انجام شود ولی آماده سازی متغیرهای استاتیک یک‌بار برای همیشه انجام می‌شود. وقتی که کلاسی را اولین بار مورد استفاده قرار میدهیم بخشی از JVM بنام ClassLoader این کلاس را در قسمتی از حافظه بارگذاری می‌کند که بخشی از این حافظه مختص متغیرهای استاتیک است کلاس است.و در همین لحظه که ClassLoader کلاس را در حافظه بارگذاری می‌نماید ویژگی‌های استاتیک به دو روش زیر مقدار دهی اولیه می‌شوند:

    1. مقدار دهی در خط:

public static int MAX_AGE = 150;

private static double PI = 3.14;

static String defaultName = theDefaultName();

private static String theDefaultName() {return "Ali Alavi";}

    1. بلوک استاتیک یا همان Static Block

public class Person {

public static int MAX_AGE ;

private static double PI ;

static String defaultName ;

private static String theDefaultName() {return "Ali Alavi";}

static{

MAX_AGE = 150;

PI = 3.14;

String s = theDefaultName();

if(s != null)

defaultName = theDefaultName();

}

}





مثال از استاتیک :

Public class Pride {

private int color;

public int getColor(){return color;}

public Pride(int c){color = c;}

public void start() {………….}

private static int length;

public static void setLength(int length){ Pride.length = length;}

}

مثال دیگر از استاتیک :

package human;

public class Person {

private string name;

private int age;

public static int MAX_AGE = 150;

public void setAge(int a){if(a<MAX_AGE) age = a;}

public static int getMAX_AGE(){return MAX_AGE; //no access t oage and name}

}

مثال دیگر از استاتیک :

public class Math {

public static double PI = 3.1415926;

public static double pow(double a, double b) {...}

public static int round(float a) {...}

public static int abs(int a) {...}

public static double max(double a, double b) {...}

public static double sqrt(double a) {...}





3.1.1)مفهوم Singleton در الگوهای طراحی Design Pattern

برای نوشتن کلاسی که فقط یک شیء از این کلاس ساخته بشود و ساختن اشياء جدید از این کلاس غیر ممکن شده وهرکس که به شیء از آن کلاس نیازدارد از همان شیء استفاده نماید(و شیء جدید نسازد و اصلاً نتواند که بسازد)

public class Singleton {

private static Singleton instance = new Singleton();

private Singleton(){ }

public static Singleton getInstance( ) {

return instance;

}

}

در این صورت باید با دستور زیر شیء تولید کرد

Singleton s = Singleton.getInstance();

در صورت استفاده از Singleton خط زیر غلط خواهد بود:

Singleton s = new Singleton(); //غلط است



3.2) final

3.2.1)متغیر ثابت(Final)

  1. برخی از متغیرها یک بار مقدار می‌گیرند و هرگز تغییر نمی‌کنند-به این‌گونه متغیرهای ثابت در زبان برنامه نویسی Constant گفته می‌شود.

  2. در جاوا متغیرهای ثابت با کلیدواژه final مشخص می‌شوند که مقدار این متغیرها قابل تغییر نیستند.

  3. هر متغیر ثابت باید بلافاصله مقدار دهی شود. مثلاً یک ویژگی ثابت باید در فرایند مقداردهی اولیه شیء مقداردهی شود(مثلا در سازنده)

  4. متغیر ثابت به شکل‌های«پارامتر ثابت» و «متغیر محلی ثابت» و «ویژگی ثابت» و «متغیر استاتیک ثابت» دیده می‌شود.

Class SomeClass{

private final String name;

public final int val =12;

void f(final int a){ final int b= a+1;}

void g(){ final String s = “123”;}

public SomeClass(String name){ this.name=name; }

  1. اگر متغیر ثابت از انواع داده اولیه باشد(مثل int و char و long و غیره) مقدارش قابل تغییر نیست. اما اگر از نوع شیء باشد دیگر به شیء دیگری نمی‌تواند ارجاع دهد

    مثال:

‫‪final‬‬ ‫‪int‬‬ ‫‪i = 2;

i=3; //غلط است

ادامه مثال

final Person p1 = new Person();

Person p2 = new Person()

p1=p2; //غلط است

p1 = new Person(); //غلط است

p1.setName(“Ali”); //درست است

  1. اگر متغیر مانظیر p1 یک شیء باشد یا اصطلاحاً یک ارجاع یا همان Reference باشد ، اگر آن را final تعریف نماییم هویت آن ثابت میماند و دیگر نمی‌تواند توسط دستورات زیر به جایی دیگر ارجاع داده شود:

p1=p2; //غلط است

p1 = new Person(); //غلط است

  1. وضعیت یا همان محتوا یا همان ویژگی یک شیء ثابت قابل تغییر است

p1.setName(“Ali”); //درست است

  1. مفاهیم سطح دسترسی (private و public و package Access ) و استاتیک بودن و Final بودن مفاهیم مستقلی هستند و هیچ ارتباطی به هم ندارند. هر متغیر استاتیک ممکن است Final باشد و یا نباشد. همچنین هر متغیر استاتیک ممکن است public باشد و یا نباشد



3.2.2)کلاس final

  1. از کلیدواژه final می‌توانیم برای تعریف یک کلاس هم استفاده نماییم.

  2. کلاس‌های final زیرکلاس ندارند-هیچ کلاسی نمی‌تواند کلاس final را extends کند (ارث‌بری از کلاس final غیرمجاز است)

  3. معنای کلاس final ، نهایی است و قابل تغییر و گسترش نیست.

  4. کلاس فاینال هیچ زیرکلاسی نخواهد داشت

  5. درهنگام ایجاد زیرکلاس برای کلاس فاینال با ارور کامپایل برخوردخواهیم کرد.

  6. با اینکار طراح کلاس اجازه نمی‌دهد تا دیگران معنی کلاس را تغییر دهند

  7. در مورد کلاس‌های final مفهوم چند ریختی وجود ندارد

  8. در بیشتر موارد کلاس‌ها را final نمی‌کنیم

final class Dog extends Animal{ . . . }





3.2.3)متد final

  1. از کلیدواژه final می‌توانیم برای تعریف یک متد هم استفاده نماییم.

  2. معنای متد فاینال نهایی است و قابل تغییر نیست.

  3. چنین متدی را در زیرکلاس نمی‌توانیم override نماییم(هیچ زیرکلاسی نمی‌تواند تعریف یک متد فاینال را override کند)

  4. با اینکار طراح متد اجازه نمی‌دهد تا دیگران معنی متد را تغییر دهند

  5. کلاس String یک کلاس final است.

  6. در مورد متدهای final مفهوم چند ریختی وجود ندارد

  7. در بیشتر موارد متدهارا final نمی‌کنیم

class Dog extends Animal{

@Override

public void talk() { ... }

public final void bark() { ... }

}









3.3) وراثت(Inheritance)

  1. زیرکلاس ویژگی‌های و رفتار اَِبَرِِکلاس خود را به ارث می‌برد

  2. زیرکلاس و اَبَرکلاس هر دو کلاس هستند

  3. هر شیء از زیرکلاس، شیء ای از اَبَرکلاس هم هست.

  4. به کلاس اصلی، کلاس پایه (BaseClass) یا اَبَرکلاس(SuperClashh) یا کلاس والد(PArentClass) می‌گویند

  5. به کلاس وارث، کلاس مشتق (DerivedClass) یا زیرکلاس(Subclass) یا کلاس فرزند(ChildClass) می‌گویند

  6. در جاوا وراٍثت با کلید واژه Extends معرفی می‌شود

class Shape{

int color;

int positionX, positionY;

}

class Circle extends Shape{

private int radius;

public double getArea(){ return 3.14*radius*radius;}

}

class Rectangle extends Shape{

private int width, length;

public double getArea(){ return width*length;}

}

  1. یک کلاس می‌تواند زیرکلاس‌های مختلفی داشته باشد.

  2. یک کلاس نمی‌تواند بصورت همزمان از چند کلاس ارث ببرد.(یک کلاس نمی‌تواند چند اَبَرکلاس داشته باشد)-(البته جاوا در شرایط خاصی امکان وراٍٍثت چندگانه را فراهم می‌کند)

    مثال(تعریف کلاس person):

public class Person {

private String name;

private Long nationalID;

public String getName() { return name; }

public void setName(String name) { this.name = name; }

public Long getNationalID() { return nationalID; }

public void setNationalID(Long nationalID) { this.nationalID = nationalID; }

public void show() {

System.out.println("Person: name="+ name + ",nationalID=" + nationalID); }

}

تغییر در کلاس فرزند:

class Student extends Person{

private String studentID;‬

public void setStudentID(String studentID) { this.studentID = studentID;}

public String getStudentID() { return studentID;}

public void takeCourse(Course course){...}

public void show(){

System.out.println("Student: name=" + getName()

+ ",nationalID=" + getNationalID()

+ ",studentID=" + studentID);

}

}

ساختن شیء از کلاس

Person p1 = new Person();

p1.setName("Ali Alavi");

p1.setNationalID(1498670972L);

p1.show();



Student st = new Student();

st.setName("Ali Alavi");

st.setNationalID(1498670972L);

st.setStudentID("89072456");‬

st.show();



  1. هرگاه یک زیرکلاس می‌سازیم و متدی را Override می‌کنیم دراین صورت حق نداریم سطح دسترسی به این متد را کاهش دهیم. مثلاً حق نداریم متدی را که در اَبَرکلاس public بوده است را در زیرکلاس private تعریف کنیم (override کنیم).چرا؟ چون:این کار قانون IS-A را نقض می‌کند و هر شیء از زیرکلاس، شیئی از جنس اَبَرکلاس هم هست و هر رفتاری که در اَبَرکلاس هست، باید برای اشیاء زیرکلاس هم قابل فراخوانی باشد. پس سطح دسترسی به متدها در زیرکلاس‌ها قابل کاهش نیست.

  2. اگر عضوی دقیقاً با همان نام در زیرکلاس هم وجود دارد. در این شرایط اگر نام متد یا ویژگی را بگوییم، نام آن متد یا ویژگی در زیرکلاس خواهد بود و محتوی زیرکلاس فراخوانی خواهد شد.

  3. گاهی در زیرکلاس می‌خواهیم از عضوی استفاده کنیم که در اَبَرکلاس تعریف شده است(متد یا ویژگی) توسط کلید واژه Super میتوان این کار را کرد.

  4. برای فراخوانی سازنده اَبَرکلاس هم می‌توانیم از super استفاده نماییم.

Super(name, id);

مثال:در دستور زیر تابع Func از کلاس اَبَرکلاس فراخوانی خواهد شد. حتی اگر متد Func در زیر کلاسدوباره تعریف شده بود باز با عبارت زیر تابع موجود در اَبَرکلاس فراخوانی می‌شد

super.Func();

  1. عبارت this و Super در مقابل هم هستند یعنی عبارت this به اجزای خود کلاس دسترسی ایجاد می‌کند ولی در super دسترسی به اجزای اَبَرکلاس ایجاد خواهد شد.

مثال یک:

class Student extends Person{

public void show(){

super.show();

System.out.println(",studentID="+studentID);

}

}

مثال دیگر دوم:

class Person{

private String name;

private String nationalID;

public Person(String name, String nationalID) {

this.name = name;

this.nationalID = nationalID;

}

}

ایجاد زیرکلاس برای مثال دوم:

class Student extends Person{

private long studentID;

public Student(String name, String id, long studentID) {

super(name, id);

this.studentID = studentID;

}

}

  1. مفهوم Override برای متدها معنی داشته وبرای متغیرهای معنی ندارد

  2. تعریف متغیر در زیر کلاس که هم‌نام متغیر اَبَرکلاس هستند، کار رایجی نیست.

  3. وقتی یک زیرکلاس تعریف می‌کنیم باید سازنده (Constructor) مشخصی از اَبَرکلاس در سازنده‌ی زیرکلاس فراخوانی شود وگرنه سازنده‌ای بدون پارامتر از اَبَرکلاس بصورت ضمنی فراخوانی خواهد شد و این کار با کلیدواژه super که باید در اولین دستور در زیرکلاس باشد صورت می‌گیرد. همچنین اگر سازنده‌ای در اَبَرکلاس نباشد، خطای کامپایل ایجاد می‌شود.

  4. سازنده‌ها به ارث نمی‌رسند. یعنی مثلاً اگر سازنده‌ای در اَبَرکلاس باشد که یک پارامتر int می‌گیرد این سازنده به زیرکلاس به ارث نمی‌رسد.

مثال:

class Person{

private String name;

private String nationalID;

public Person(String name, String nationalID) {

this.name = name;

this.nationalID = nationalID;

}

}

class Student extends Person{

private long studentID;

public Student(String name, String id, long studentID) {

super(name, id);

this.studentID = studentID;

}

}

ادامه مثال؛ برای ایجاد اشیاءاز کلاس‌های بالا، باید به صورت زیر اقدام کرد:

Person p = new Person("Ali Alavi", "1290562352");

Student s = new Student("Ali Alavi", "1290562352", 94072456);

  1. روند مقداردهی اولیه در وراثت:1-یکبار برای همیشه کلاس زیرکلاس بارگذاری می‌شود ۲- قبل از زیرکلاس اَبَرکلاس بارگذاری می‌شود ۳- اگر اَبَرکلاس هم از کلاس دیگری ارث‌بری کرده باشد، آن کلاس هم قبلاً بارگداری شده است.(یادآوری:هنگام بارگذاری کلاس، ویژگی‌های استاتیک مقداردهی اولیه می‌شوند).0

  2. هر بار که یک شیء از نوع زیرکلاس ایجاد می‌شود : ۱-ابتدا بخشی از شیء که در اَبَرکلاس تعریف شده، مقدار دهی اولیه می‌شود. ۲- سپس سایر ویژگی‌های شیء که در زیرکلاس تعریف شده، آماده می‌شود.

  3. برای مقداردهی اولیه اشیاء یکبار برای هرکلاس این اتفاقات می‌افتد:1-مقداردهی درخط متغیر‌های استاتیک در اَبَرکلاس ۲-بلوک استاتیک در اَبَرکلاس فراخوانی می‌شود۳-مقداردهی درخط متغیرهای استاتیک زیرکلاس ۴-بلوک استاتیک در زیرکلاس فراخوانی می‌شود.

  4. هربارکه یک شیء از زیرکلاس ایجاد بشود :1- مقداردهی درخط ویژگی‌های اَبَرکلاس ۲- بلوک مقداردهی اولیه در اَبَرکلاس ۳-سازنده اَبَرکلاس ۴- مقداردهی درخط ویژگی‌های زیرکلاس ۲- بلوک مقداردهی اولیه در زیرکلاس۳-سازنده زیرکلاس





3.4) Abstract (مفهوم انتزاعی)

انتزاعی بودن یک کلاس یا متد باید توسط برنامه نویس مشخص شود و اینکار با کلیدواژه abstract انجام می‌شود

3.4.1)متد انتزاعی

  1. متدی که برای همه اشیاء یک کلاس وجود دارد، اما جزییات دقیق و پیاده‌سازی این متد در آن کلاس غیرممکن است.باید در هر زیرکلاس پیاده‌سازی شود.چنین متدی در اَبَرکلاس متد انتزاعی خوانده می‌شود.

  2. متد Concrete در نقطه مقابل Abstract Method قراردارد، متد Concrete متدی است که پیاده‌سازی کاملاً مشخصی داشته و انتزاعی نیست.

  3. گاهی همه متدهای یک کلاس،‌ انتزاعی هستند.

  4. متد انتزاعی، دارای بدنه و پیاده‌سازی نیست. قرار نیست که پیاده‌سازی شود و باید توسط یک زیرکلاس پیاده‌سازی شود.

Abstract class Animal{ . . .}

public abstract void talk();

مثال:

abstract class Animal {

private String name;

public void setName(String name) { this.name = name;}

public String getName() { return name;}

public abstract void talk();

}

class Cat extends Animal{

public void talk() { System.out.println("Meww!!");}

}

مثال دوم:

public abstract class Shape {

public abstract double getArea();

public abstract double getPerimeter();

}

ادامه مثاال دوم:

public class Circle extends Shape {

private double radius;

public double getRadius() {return radius; }

public void setRadius(double radius) {this.radius=radius;}

public double getArea() {return Math.pow(radius, 2) * Math.PI;}

public double getPerimiter() {return 2*radius * Matn.PI;}

}

ادامه مثاال دوم:

public class Rectangle extends Shape{

private double width, length;

public double getWidth(){ return width; }

public void setWidth(double width){ this.width=width;}

public double getLength(){ return length; }

public void setLength(double length){ this.length=length;}

public double getArea(){ return length * width;}

public double getPremiter() { return 2 -(length + width);}

}

ادامه مثاال دوم:

public class Square extends Shape{

private double length;

public fouble getLength(){ return length; }

public void setLength(double length){ this.length=length;}

public double getArea(){ return length * length;}

public double getPrimeter(){ return 4 * length;}

}





3.4.2)کلاس انتزاعی

  1. کلاسی که هیچ شیئی مستقیماً از آن ایجاد نمی‌شود.

  2. اگر شیئی از جنس این کلاس است، باید از یکی از زیرکلاس‌هایش تولید شود.

  3. کلاس‌هایی که متد انتزاعی دارند، قطعاً کلاس انتزاعی هستند.

  4. کلاسی که متد انتزاعی دارد، تعریف برخی رفتارها را ندارد پس باید در زمان پیاده‌سازی در زیرکلاس‌ها تعریف واقعی شوند(به Concrete method تبدیل شوند)

  5. اگر در کلاسی یک متد انتزاعی تعریف کنیم، باید آن کلاس را هم انتزاعی کنیم و حتماً باید قبل از کلاس کلیدواژه abstract اضافه شود.

  6. اگر کلاسی یک کلاس انتزاعی را به ارث ببرد و همه متدهای انتزاعی آنرا پیاده‌سازی نکند، کلاس جدید هم انتزاعی است و باید با پیشوند abstract تعریف شود(چون بخاطر ارث‌بری دارای متدی است که هنوز پیاده‌سازی نشده و انتزاعی است.)

  7. از کلاس انتزاعی نمی‌توانیم نمونه‌ای بسازیم زیرا استفاده از new برای یک کلاس انتزاعی باعث خطای کامپایل می‌شود.

  8. بک کلاسی که هیچ متد Abstract در آن نیست(حتی به ارث هم نبرده است) هم می‌تواند بصورت انتزاعی تعریف شود(در ابتدای نام کلاس عبارت abstract آورده شود). این کار معمولاً به منظور جلوگیری از ایجاد شیء از این کلاس کاربرد دارد. همچنین برای اجباری کردن ایجاد زیرکلاس‌هایی از آن نیز کاربرد دارد.به مثال توجه نمایید. برنامه نویس طوری طراحی کرده که اجازه ندهد از آن شیئی ایجاد شود :

‫‪abstract‬‬ ‫‪class‬‬ ‫Human‬‬ {

‫‪private‬‬ ‫‪String‬‬ name ;

‫‪public‬‬ ‫‪String‬‬ getName‬‬(){ ‫‪return‬‬ ‫;‪name‬‬‫}‬

}‬





3.5) interface (واسط)

  1. همه متدهای یک کلاس، انتزاعی باشند(متد غیر abstract در آن وجود ندارد)

  2. واسط وضعیت و حالت (state) اشیاءش را توصیف نمی‌کند.و درگیر جزییات نمی‌شود.و کلیات رفتار شیء را توصیف می‌کند.

  3. هیچ متغیر(ویژگی) در آن تعریف نشده باشد. (تعریف یک متغیر در یک واسط رایج نیست)

  4. interface مانند یک کلاس کاملاً انتزاعی است (Pure Abstract Class)

  5. هرمتدی که در interface تعریف می‌شود، بصورت ضمنی هم public بوده و هم abstract است.

  6. هر متغیری که در واسط تعریف شود بصورت ضمنی: Public و static و final هست.

  7. واسط نشان میدهد که شیء چه رفتارها و عمل‌کردی دارد ولی نحوه اجرای این رفتار‌ها را توصیف نمی‌کند(پیاده سازی ندارد)

  8. دو مثال زیر از لحاظ معنا و کاربرد تقریباً مشابه هستند: حالت اول:

‫‪public‬‬ ‫‪interface‬‬ ‫‪Shape‬‬ ‫{‬

‫‪double getArea();

‫‪double‬‬ ‪getPerimeter‬‬();

}‬

حالت دوم:

public anstract class Shape {

public abstract double getArea();

public abstract double getPrimeter();

}

  1. برای ارث‌بری از یک کلاس، از کلیدواژه extends استفاده می‌شود.

  2. برای ارث‌بری یک کلاس از یک واسط، ازکلیدواژه implements استفاده می‌شود

class Rectangle implements Shape { . . . }

  1. بین یک کلاس و واسطی که پیاده‌سازی کرده‌ایم، رابطه IS-A برقرار است:

Rectangle is a Shape

  1. اگر یک کلاسی یک واسط را پیاده‌سازی کند باید همه متدهای آن را هم تعریف کند وگرنه این کلاس متدهای انتزاعی را به ارث برده است و خودش هم باید انتزاعی شود

  2. یک واسط می‌تواند از واسط یا واسط‌های دیگر ارث‌بری کند که در این صورت همه متدهای انتزاعی اَبَرکلاس به زیرواسط به ارث می‌رسند که با کلیدواژه extends انجام می‌شود. همچنین در این حالت رابطه is-a برقرار خواهد بود

  3. یک واسط نمی‌توان از یک کلاس ارث‌بری کند(غیر مجاز و خطای کامپایل)

‫‪‫‪interface‬‬ ‫CanRun‬‬{

‫‪void‬‬ ‫‪run‬‬();

}‬

‫‪interface‬‬ CanThink‬‬{

‫‪void‬‬ ‪think‬‬();

}

interface‬‬ ‫‪CanTalk‬‬ ‫‪extends‬‬ CanThink‬‬{

void ‪talk‬‬();

}‬

‫‪interface‬‬ ‫‪Human‬‬ ‫‪extends‬‬ ‫‪CanRun,‬‬CanTalk‬‬{

void ‪think‬‬();

}‬

  1. یک کلاس فقط و فقط از یک کلاس می‌تواند ارث‌بری کند(extends)

  2. در وراثت در مفهوم واسط هرکلاس ، اَبَرکلاس مشخصی دارد که با کلیدواژه extends مشخص می‌شود وگرنه اگر اَبَرکلاس تصریح نشود ، زیرکلاس Object خواهد بود

  3. یک کلاس صفر یا چند واسط را پیاده‌سازی می‌کند(implements)

  4. یک کلاس از صفر یا چند واسط ارث‌بری میکند(extends)

interface CanFight { void fight(); }

interface CanSwim { void swim(); }

interface CanFly() { void fly(); }

Class ActionCharacter {

private String name;

Public String getName() {return name; }

}

class Hero extends ActionCharacter implements CanFight, CanSwim, CanFly{

public void swim(){}

public void fly(){}

public void fight(){}

}

  1. ارث‌بری مثال زیر غلط است:

interface A{ void f(); }

interface B{ int f(); }

abstract class C implements A,B{} //غلط است

  1. اگر متغیر در یک واسط تعریف شده باشد در این صورت بطور ضمنی ثابت و استاتیک و عمومی(public) خواهد بود.

Interface Humans{

int MAX_AGE=150; or public static final int MAX_AGE=150;

}

  1. امکان تعریف سازنده (Constructor) در واسط وجود ندارد زیرا هدف سازنده مقداردهی اولیه ویژگی‌های شیء است(Field یا Property) و نیز سازنده وضعیت اولیه شیء را آماده می‌کند-واسط حالت شیء را توصیف نمی‌کند.

  2. بهتر است حتی‌الامکان طراحی کلاس‌ها و متد‌های ما به واسطه ها وابسته باشند.

  3. از جاوا8 به بعد یک واسط میتوان متدهای غیر انتزاعی داشته باشد. که به این متدها، متد پیش‌فرض(DefaultMethod ) گفته می‌شود.

‫‪interface‬‬ ‫‪Person‬‬ ‫{‬

‫‪Date‬‬ getBirthDate‬‬();

‫‪default‬‬ ‫‪Integer‬‬ age(){

‫‪long‬‬ ‫‪diff‬‬ ‫=‬ ‫‪new ‪Date.).getTime()-getBirthDate().getTime‬‬();

‫‪return‬‬ (int)‪(diff‬‬ ‫‪/‬‬ (1000L*60*60*24*365‬‬));

}‬

  1. همچنین یک کلاس می‌تواند چند واسط را پیاده‌سازی کند - بنابراین امکان وراثت چندگانه در جاوا۸ به شکلی محدود وجود دارد









3.6) Package

  1. هر بسته در جاوا ممکن است شامل تعدادی کلاس باشد

  2. امکانی برای طبقه بندی و گروه بندی کلاس‌های جاوا است(مانند مفهوم فولدر در مدیریت فایل)

  3. هربسته شامل کلاس‌هایی است که به یک دسته تعلق دارند ویا کاربرد مشابهی دارند

  4. یک فضای نام‌گذاری(nameSpace) یکتا برای کلاس‌ها فراهم می‌کند.

  5. نام دقیق کلاس = نام بسته + نام کلاس

  6. هر بسته می‌تواند شمال بسته های دیگر باشد(سلسله مراتبی از بسته‌ها)

  7. کلاس‌های یک بسته در یک شاخه(Folder) نگهداری می‌شوند

  8. برای قرار دادن یک بسته در یک کلاس، فایل کلاس را درون شاخه بسته قرار میدهیم

  9. می‌توانیم در اولین خط از تعریف کلاس، با استفاده از دستور package آن را معرفی می‌کنیم:

package ir.MyCompany;

  1. معمولاً نام‌گذاری بسته‌ها از کل به جزء صورت می‌گیرد: دامنه>شرکت>دپارتمان>پروژه>زیرمجموعه

Files.Securent.It.Behrooz.Com

  1. باکمک ستاره (*) همه کلاس‌های یک بسته قابل استفاده می‌شوند

import java.util.*;

  1. کلاس‌های بسته java.lang که شامل بسته‌های اصلی زبان جاوا است نیاز به imporet شدن ندارد. مثلاً کلاس String و Math از این بسته است.

  2. دستور import فقط برای کامپایلر است.(جایگزین شدن نام کلاس با نام کامل کلاس‌ها و آدرس‌ها و درنهایت کامپایل شدن برنامه بدون وجود داشتن دستورات import)-دستور import در کلاس کامپایل شده دیده نمی‌شود(فایل .class یا bytecode)





3.7) Mutable Object یا اشیاء تغییر پذیر

  1. امکان تغییر وضعیت اشیاء در اینگونه اشیاء وجود دارد

  2. اشیاءای که تغییرپذیرند معمولاً Setter دارند

  3. به متدهای Setter یک متغیر اصطلاحاً mutator می‌گویند

  4. طراح کلاس تصمیم میگیرد نمونه‌های این کلاس تغییرپذیر باشندیا خیر



3.8) Immutable Object یا اشیاء تغییر ناپذیر

  1. ویژگی‌های اینگونه اشیاء بعد از ساخت این اشیاء قابل تغییر نیست

  2. تغییر ناپذیر بودن یک شیء با ثابت بودن متفاوت است.

  3. این موضوع درباره وضعیت یا state یا حالت و ویژگی‌های درون اشیاء هست

  4. یک مفهوم است و کلید واژه خاصی ندارد

  5. مزایای آن: سادگی و فهم ساده‌تر و کارایی بهتر برنامه و سهولت و بهینگی در موازی کاری یا همان Thread-safe

  6. خیلی از کلاسهایی که میشناسیم از این نوع است: مثل String که متد setValue ندارد







3.9) Enumeration

  1. فرض شود که یک کلاس، تعداد محدودی و مشخصی شیء خواهد داشت و نمونه‌های این کلاس محدود هستند و این نمونه‌های در آینده اضافه نخواهد شد. مثال: کلاس نوع دانشجو که حتماً چیزی بین لیسانس و فوق لیسانس و دکترا و این قبیل است -مثال: وضعیت یک اس ام اس را نام برد که می‌تواند در وضعیت ۱- ارسال شده ۲- در دست ارسال ۳-مواجه با خطا-مثال: رنگ که آبی و سبز و مشکی و قرمز- که برای پیاده‌سازی چنین مواردی از enum استفاده می‌شود.

  2. مثال رنگ را با دوحالت زیر که یکی با enum و دومی بدون enum است پیاده‌سازی می‌کنیم:

حالت بدون Enum:

class Color{

public static final Color BLACK = new Color();

public static final Color BLUE = new Color();

public static final Color GREEN = new Color();

public static final Color RED = new Color();

private Color() { }

}

حالت Enum:

enum Color { BLACK, BLUE, GREEN, RED }

برای استفاده از این مورد باید به شکل زیر اقدام کرد:

Color color = Color.BLACK;

  1. اگر یک کلاس تعداد محدود و مشخصی شیء دارد بهتر است بجای کلاس با کلیدواژه enum تعریف شود و همان جا همه اشیاء (نمونه‌ها) آن مشخص شود.

  2. همه نمونه‌های enum بصورت ضمنی public , static, final هستند.

  3. هیچ نمونه (شیء) جدیدی نمی‌تواند ایجاد شود(نمونه سازی با کمک new با ارور مواجه خواهد شد)

  4. ارث‌بری از enum امکان‌پذیر نیست











3.10) Iterator

  1. از جاوا 5 به بعد، for each برای آرایه‌ها و collection ها ممکن شد

int[] array = {1,2,3,7};

for (int i : array)

System.out.println(i);

  1. کاربرد دیگر در لیست

List<Integer> list ;

...

for (Integer i : list)

System.out.println(i);

مثال:

List<Integer> list = ... ;

Iterator<Integer> iterator = list.iterator();

while(iterator.hasNext()){

Integer i = iterator.next();

System.out.println(i);

}





3.10.1)متد Iterator

  1. متد iterator در واسط java.lang.Iterable تعریف شده است

  2. واسط Collection ، از واسط Iterable ارث‌بری کرده است

  3. بنابراین List ها و Set ها همگی Iterable هستند

  4. در واقع همه کلاس‌هایی که Iterable هستند، امکان for each دارند

  5. امکان for each در نسخه‌های جدید جاوا با کمک iterator پیاده شده است

public interface Iterable<T> {

Iterator<T> iterator();

...

}

  1. اینترفیس Iterator

public interface Iterator<E> {

boolean hasNext();

E next(); //رفتن به خونه بعدی

void remove();

}

  1. واسط‌های Collection هم Iterator را ارث‌بری می‌کنند:

public interface Collection<E> extends Iterable<E> {…}

مثال

List<Integer> list = new ArrayList<Integer>();

for(int i=0;i<10;i++)

list.add(i);



Iterator<Integer> iterator = list.iterator();

while(iterator.hasNext()){

Integer value = iterator.next();

if(value%2==0)

iterator.remove();

}

System.out.println(list.size());



  1. جاوا از تغییرات همزمان جلوگیری می‌کند

  2. اگر یک ظرف به واسطه یکی از متدهایش تغییر کند، همه iterator هایی که قبلاً روی این ظرف گرفته شده، غیرمعتبر می‌شوند. هر عملیاتی که از این پس روی این iterator های غیرمعتبر انجام شود، منجر به پرتاب خطای ConcurrentModificationException می‌شود. به این تکنیک، شکست سریع (Fail Fast) گفته می‌شود

  3. با تغییر یک ظرف توسط یک iterator ، سایر iterator ها غیرقابل‌استفاده می‌شوند. این تکنیک، روش جاوا برای جلوگیری از تغییر همزمان است.

  4. مثال:در این مثال itr غیر معتبر می‌شود و منجر به ارسال خطای ConcurrentModificationException می‌شود.

Collection<String> c = new ArrayList<String>();

Iterator<String> itr = c.iterator();

c.add("An object");

String s = itr.next();



  1. مثال:بلافاصله بعد از اجرای متد remove روی این خط خطا دریافت می‌کنیم. iterator ای که با کمک آن حلقه for در حال اجراست نامعتبر می‌شود:

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



list.add("A");

list.add("B");

list.add("C");



for (String s : list)

if(s.equals("A"))

list.remove(s);



  1. مثال مهم: این راه‌حل منجر به ConcurrentModificationException می‌شود-پس از این مورد استفاده نکنید:

void removeAli(List<String> list){

for (String string : list)

if(string.startsWith("Ali"))

list.remove(string);

}

  1. مثال مهم: راه حل صحیح اول مثال بالا- از این روش استفاده نمایید:

public static void removeAli(List<String> list){

Iterator<String> iterator = list.iterator();

while(iterator.hasNext()) {

String string = iterator.next();

if(string.startsWith("Ali"))

iterator.remove();

}

}

  1. مثال مهم: راه حل صحیح دوم مثال بالا- از این روش استفاده نمایید:

public static void removeAli(List<String> list){

for (int i = list.size()-1; i >= 0; i--)

if(list.get(i).startsWith("Ali"))

list.remove(i);

}





















فصل 4) متدهای مهم

برخی متدهای هستند که از اهمیت ویژه‌ای برخوردارند که به برخی از آن‌ها اشاره می‌نماییم.





4.1) Constructor

هر بار که از یک کلاس استفاده می‌شود، درصورتی که آن کلاس دارای تابع Constructor باشد، این تابع فراخوانی خواهد شد.

Public class Circle {

private double radius;

public Circle(double r) {

radius = r;

}

public double getArea(){

return radius*radus * 3.14;

}

}

همچنین برای صدا زدن از فرمت زیر استفاده می‌شود:

public static void main(String[] args) {

Circle c = new Circle(2);

Systenm.out.println(c.getArea());

}

تابع Constructor :

  1. باید دقیقاً هم‌نام کلاس باشد.

  2. هیچ نوع برگشتی نباید داشته باشد

  3. سازنده یک متد خاص است:

  4. بجای متد init که برای مقدار دهی اولیه کاربرد دارد استفاه می‌شود.

  5. زمانی که یک شی‌ء جدید ایجاد می‌کنیم سازنده بصورت خودکار فراخوانی می‌شود.مثلا وقتی که با کمک new شیء جدیدی می‌سازیم. به این ترتیب شیء همواره از دو تولد در حالت معتبر خواهد بود.

  6. یک سازنده ممکن است پارامترهایی داشته باشد.

  7. یک کلاس می‌تواند سازنده‌های مختلفی داشته باشد.(به شرط اینکه پارامتر‌های مختلفی داشته باشد)

Public class Circle {

private double radius;

public Circle(double r) {

radius = r;

}

public double getArea(){

return radius*radus * 3.14;

}



public Circle(){

}

}

  1. اگر برنامه نویس هیچ سازنده‌ای برای یک کلاس تعریف نکند در این صورت کامپایلر حاوا بصورت خودکار یک سازنده پیش‌فرض برای آن کلاس درنظر می‌گیرد-سازنده پیش‌فرض (Default Constructor) هیچ پارامتری ندارد و بدنه این سازنده خالی است.

  2. وقتی برنامه نویس اولین constructor را تعریف نماید جاوا سازنده پیش‌فرض برای این کلاس اضافه نمی‌کند.

  3. هرگاه یک شیء ساخته می‌شود سازنده‌اش فراخوانی می‌شود. یعنی سازنده باید ویژگی‌های شیء را مقدار دهی نماید. درصورت لزوم ، ویژگی‌هایی که خودشان شیء هستند را هم ایجاد نماید.

Public class Car {

private Engine engine;

private Tyre[] tyres;

public Car() {

engine = new Engine()’

tyres = new Tyre[4];

for(int I = 0; I < tyres.length; i++) {

tyres[i] = new Tyre();

}

}

}

  1. اگر سازنده مقدار یک ویژگی (Property) را مشخص نکند در این صورت هر ویژگی مقدار پیش‌فرض نوع داده خودش را میگیرد-یعنی integer , char , long مقدار صفر و Boolean مقدار False و متغیر‌های ارجاعی (اشیاء) مقدار Null را به خود میگیرد

  2. گاهی یک تابع سازنده در بدنه خود یک سازنده دیگر را فراخوانی می‌نماید. در این صورت باید این فراخوانی حتماً اولین دستور سازنده باشد، این فراخوانی به کمک پارامتر this صورت می‌گیرد.

public class Country {

private String name;

Private int population;



public Country(){

name = “Iran” ;

}

public Country(int number){

this();

population = number;

}

public Country(String n, int number) {

this(number);

name = n;

}

}





4.2) Destructor

برخی زبان‌های برنامه‌نویسی مانند سی پلاس پلاس امکانی با عنوان نابودگر دارند که این مفهوم در مقابل مفهوم سازنده(Constructor) است.

جاوا نیازی به Destructor ندارد و مفهوم Garbage Collector کارهای مفهوم Destructor را انجام می‌دهد.



4.3) متد finalize

  1. هرچند جاوا Destructor ندارد اما برای هرکلاس متد ویژه‌ای با نام finalize قابل تعریف است و برنامه نویس می‌تواند این متد را ایجاد نماید.

  2. هروقت Garbage Collection بخواهد یک شیء را آزاد نماید قبل از آزاد شدن شیء متد Finalize از آن شیء را فراخوانی می‌کند.(وصیت نامه یک شیء)

  3. می‌توان بصورت دستی فرایند ذباله روبی را در این متد به اجرا در آورد:

public class Circle {

private double radius;

public Circle(double r) {radius = r;}

public void finalize() {System.out.println(“Finalize...”);}

public static void f(){

Circle c = new Circle(2);

System.out.println(c.radius);

public static void main(String[] args){

f();

System.gc();

}

}

  1. زباله روب یا همان Garbage Collection فقط درباره حافظه هست.

  2. ممکن است یک شیء منابعی غیر از حافظه را در اختیار گرفته باشد و این منابع را هنوز آزاد نکرده باشد مثل باز بودن یک فایل یا دسترسی به یک دیتابیس

  3. پیاده‌سازی Finalize کار رایجی نیست و کاربردهای خاصی دارد



4.4) متدToString

اگر یک شیء قراز است به رشته تبدیل بشود باید متد ToString پیاده‌سازی شود.

همه کلاس‌ها این متد را دارند اما پیاده‌سازی صحیح آن را باید برای کلاس جدید تعریف کنیم

‫‪Person‬‬ ‫‪person‬‬ ‫=‬ ‫‪new‬‬ ‫‪Person("Ali",‬‬ ‫25)‪;

‫‪String‬‬ ‫‪s‬‬ ‫=‬ ‫‪person.toString‬‬();

مثال دیگر:

‫‪Integer‬‬ ‫‪number‬‬ ‫=‬ ‫‪new‬‬ ‫Integer(12‬‬);

‫‪String‬‬ ‫‪s‬‬ ‫=‬ ‫‪number.toString‬‬();

مثال دیگر:

package ir.javacup.oop;

public class Circle {

private double radius;

public Circle(double radius) {this.radius = radius;}

public String toString() {return "Circle [radius=" + radius + "]";}

public static void main(String[] args) {

Circle c = new Circle(2.0);

System.out.println(c.toString());

}

}

در مثال بالا اگر متد ToString را تعریف نمیکردیم خروجی متد پیش‌فرض ToString جاوا عبارت زیر میشد:

ir.javacup.oopadeeperlook.Circle@15db9742

اما وقتی این متد را تعریف کردیم خروجی مطلوب مشابه زیر شده است:

Circle [radius=2.0]



4.5) متد Equals

  1. برای مقایسه دو متغیر و بررسی تساوی.

  2. اگر متغیرها از نوع Primitive باشند (مثلاً int , boolean, char , long) عملگر == مناسب است و تساوی را می‌توان با همین دو مساوی بررسی کرد.

  3. برای مقایسه اعداد اعشاری به روش عملگر == بهتر است که بخاطر نوع خاص ذخیره سازی اعداد اعشاری استفاده نشود.

  4. در مقایسه از نوع ارجاع( مثلاً دو شیء از یک کلاس یا دو رشته) در این صورت عملگر == تساوی ارجاع‌ها را بررسی می‌کند و چک می‌کند که دو متغیر به یک جا از حافظه اشاره می‌کند یا خیر و تساوی محتوی دو شیء را بررسی نمی‌کند

  5. عملگر == هویت (Identity) را بررسی می‌کند و نه وضعیت یا محتوی (حالت یا State)

مثال:

String s = new String("Ali");

String t = new String("Ali");

if(s == t)

System.out.println("s==t");

else

System.out.println("s!=t");

OUTPUT: s!=t

  1. برای مقایسه محتوی دو شیء از تابع Equal استفاده می‌شود.

مثال:

String s = new String("Ali");

String t = new String("Ali");

if(s.equals(t))

System.out.println("s equals t");

else

System.out.println("s is not equals t");

OUTPUT: s equals t

  1. همه کلاس‌های مهم جاوا (نظیر String و یا Integer و یا Character و غیره) متد equals مناسبی دارند که این متد تساوی محتوی دو شیء را بررسی می‌کند

  2. اگر بخواهیم خودمان این متد را تعریف نماییم باید یک شیء بصورت پارامتر بگیرد و مقدار Boolean برگرداند. این منتد ویژگی‌های شیء موجود در پارامتر را با ویژگی‌های خودش بررسی و مقایسه می‌کند و در نهایت وضعیت بصورت درست یا غلط برگردانده می‌شود.

  3. در تعریف equals محتوی پارامتر با this مقایسه می‌شود.

    مثال یکم:

public class Person {

private String nationalID;‬

private String name;

private String email;

private int age;

public boolean equals(Person other) {

return nationalID.equals(other.nationalID);

}

}

در ادامه مثال یکم:

Person p1 = new Person("1290786547", "Ali Alavi");

Person p2 = new Person("1290786547", "Taghi Taghavi");

Person p3 = new Person("0578905672", "Taghi Taghavi");

System.out.println(p1.equals(p2));

System.out.println(p2.equals(p3));



  1. بسياری از ساختمان‌داده‌های جاوا نظیر متد contains تساوی اعضای فهرست را بررسی می‌کنند و به دنبال یک شیء مساوی شیء موردنظر می‌گردد این کار با کمک متد equals انجام می‌شود. همچنین متدهایی مثل indexOf(Object o) وremove(Object o) نیز equals را صدا می‌کنند

  2. در ساختمان داده‌ها متد equals روی اشیاء فهرست فراخوانی می‌شود و شیء موردنظر به آن پاس می‌شود

  3. در ساختنمان داده‌ها در مجموعه‌ها (مثل HashSet) تکراری بودن عضو جدید با کمک equals بررسی می‌شود

  4. در ساختمان داده‌ها و Containerها اگر بخواهیم ظرفی از جنس یک کلاس دلخواه داشته باشیم، باید متد equals مناسبی برای کلاس موردنظر پیاده‌سازی شده باشد

مثال:خروجی کد زیر False هست و این مشکل باید با پیاده‌سازی متد equals مناسب حل شود:

class Student {

private String name;

public Student(String name) {

this.name = name;

}

}



main(){

List<Student> list = new ArrayList<Student>();

list.add(new Student("Ali"));

System.out.println(list.contains(new Student("Ali")));

}

در مثال بالا،‌شکل صحیح متد equals بصورت زیر است(البته متد equals زیر کامل و دقیق نیست وجزئیاتی مثل null بودن پارامتر را بررسی نمی‌کند):

public boolean equals(Object obj) {

Student other = (Student) obj;

if (!name.equals(other.name))

return false;

return true;

}









4.6) متدهای کلاس Object

  1. در جاوا کلاسی بنام Object هست که روت یا سرشاخه همه کلاس‌های جاوا هستند و همه کلاس‌ها حتماً فرزند این کلاس هستند. همه کلاس‌ها از این کلاس ارث بری می‌کنند.

  2. کلاس‌هایی که هنگام تعریف از کلیدواژه extends استفاده می‌کنند بصورت غیرمستقیم از Object ارث‌بری می‌کنند.

  3. کلاس Object متدهایی آشنا از قبیل HashCode و equals و finalize و tostring و غیره دارد.









4.7) متد getClass

  1. اولین باری که یک کلاس استفاده می‌شود این کلاس در حافظه بارگذاری می‌شود(Dynamic Loading)

  2. اطلاعات مربوط به این کلاس در شیئی با نام «شیء کلاس» در حافظه جای می‌گیرد(Class Object)

  3. هر شیئی یک ارجاع به «شیء کلاس» خودش را دارد

  4. این ارجاع به کمک متد getClass برمی‌گردد

  5. متد getClass در کلاس Object پیاده‌سازی شده است

  6. متد getClass بصورت final پیاده‌سازی شده است

‫‪Animal‬‬ ‫‪a‬‬ ‫=‬ ‫‪new‬‬ ‫Dog(“Fido”);

‫‪String‬‬ ‫‪s‬‬ ‫=‬ ‫a.getClass().getSimpleName‬‬();

‫‪s = a.getClass().getName();







4.8) Hash

4.8.1)تکنیک Hash

  1. برخی از ساختمان‌داده‌های جاوا مبتنی بر تکنیک Hash هستند(مانند HashSet و HashMap)

  2. از hash برای محاسبه محل ذخیره شیء استفاده می‌شود

  3. از هر شیء که قرار است ذخیره شود، یک عدد صحیح استخراج شود و این عدد صحیح (hash)، مبتنی بر ويژگی‌های داخل شیء محاسبه شود

  4. ممکن است دو شیء مقدار hash مساوی داشته باشند ولی تابع hash مناسب، اعدادی حتی‌الامکان متفاوت برای اشیاء متفاوت برمی‌گرداند

  5. دو شیء با ويژگی‌های مساوی، باید مقدار hash مساوی برگردانند

  6. مقدار hash تصادفی نیست

4.8.2)متدHashCode

  1. متد hashCode از کلاس Object به همه کلاس‌ها به ارث می‌رسد

  2. می‌توانیم این متد را override کنیم و معنای مناسبی برای آن پیاده کنیم

  3. با کمک hashCode یک شیء به یک عدد صحیح (hash) تبدیل می‌شود

  4. از hash برای جایابی در حافظه و دسترسی سریع به اشیاء استفاده می‌شود

  5. متد hashCode مناسب، از فیلدهای شیء استفاده می‌کند و عددی حتی‌الامکان متفاوت برمی‌گرداند

  6. از امکانات IDE (مثلاً eclipse) برای تولید متدهای equals و hashCode استفاده کنید

  7. اگر برای مقایسه دو شیء متد equals مقدار true برمی‌گرداند،

  8. متد hashCode این دو شیء هم باید مساوی باشند، و نه لزوماً برعکس.

مثال:مقدار False برمیگرداند.

class Student {

private String name;

public Student(String name) {

this.name = name;

}

}

main(){

Set<Student> set = new HashSet<Student>();

set.add(new Student("Ali"));

System.out.println(set.contains(new Student("Ali")));

}

راه حل: باید برای کلاس Student هم متد equals و هم hashCode مناسبی پیاده کنیم. پیاده‌سازی equals کافی نیست، زیرا HashSet مبتنی بر hashCode کار می‌کند

مثلاً:

public int hashCode() {

return 31 + ((name == null) ? 0 : name.hashCode());

}





4.9) واسط Comparable

public interface Comparable<T> {

public int compareTo(T o);

}

  1. اگر کلاسی واسط Comparable را پیاده کند، یعنی برای اشیاء این شیء ترتیب معنا دارد

4.9.1)متد compareTo

  1. شیء جاری را با پارامتر متد مقایسه می‌کند و یک عدد برمی‌گرداند

  1. منفی، صفر و مثبت بودن این عدد به ترتیب یعنی این شیء کوچک‌تر، مساوی یا بزرگ‌تر از پارامتر متد است







مثال

class java.util.Date implements Comparable<Date>{

public int compareTo(Date anotherDate) {

long thisTime = getMillisOf(this);

long anotherTime = getMillisOf(anotherDate);

return (thisTime<anotherTime ? -1 :

(thisTime==anotherTime ? 0 : 1));

}

}

مثال

//Deprecated Constructors:

Date d1 = new Date(2015, 10, 21);

Date d2 = new Date(2013, 7, 26);

Date d3 = new Date(2013, 7, 26);

System.out.println(d1.compareTo(d2));

System.out.println(d2.compareTo(d1));

System.out.println(d2.compareTo(d3));

OUT:1

OUT:-1

OUT:0





  1. برای هر کلاس جدید که ترتیب اشیاء در آن معنی و اهمیت دارد، کلاس را فرزند Comparable کنید و متد compareTo مناسب برای آن پیاده‌سازی کنید

  2. مثال برای Comprator:

class Student implements Comparable<Student> {

int age;

double grade;

public int compareTo(Student s) {

return (this.grade<s.grade ? -1 :

(this.grade==s.grade ? 0 : +1));

}

public Student(int age, double grade) {

this.age = age;

this.grade = grade;

}

}

ادامه:

class StudentComparator implements Comparator<Student>{

public int compare(Student s1, Student s2) {

return s1.age<s2.age? -1:(s1.age==s2.age?0 : +1);

}

}

ادامه:

StudentComparator comparator = new StudentComparator();

Student s1 = new Student(21, 17.5);

Student s2 = new Student(20, 18.5);

System.out.println(s1.compareTo(s2));

System.out.println(comparator.compare(s1,s2));



فصل 5) سطوح دسترسی

5.1) سطح دسترسیAccess Modifier یا Access Specifier

World

Subclass

Package

Class

Modifier

Yes

Yes

Yes

Yes

Public

No

Yes

Yes

Yes

protected

No

No

Yes

Yes

No Modifier

No

No

No

Yes

Private



5.1.1)Public

  1. نوعی سطوح دسترسی به متد و ویژگی‌ها و کلاس‌ها

  2. با قرار دادن این سطح دسترسی: قطعه کد از همه جا بصورت مستقیم در دسترس می‌شود و دسترسی به آن آزاد می‌باشد.

  3. موقع تعریف یک کلاس می‌توانیم کلمه public را قید کنیم یا نکنیم-اگر قید نشود چنین کلاسی فقط در کلاس‌هایی که در همان بسته قرار گرفته‌اند قابل استفاده است.(package Access)

  4. در داخل یک فایل جاوا می‌توانیم صفر یا چند کلاس غیرpublic تعریف نماییم.

  5. هر فایل جاوا حداکثر یک کلاس public دارد.(کلاس عمومی در صورت وجود باید دقیقاً همنام فایل باشد)-به زبان دیگر اگر کلاس public در داخل یک فایل جاوا تعریف می‌شود فقط یک کلاس می‌تواند باشد و دقیقاً باید هم نام فایل [جاوایی که کلاس در آن نوشته شده است] باشد

  6. ممکن است یک فایل جاوا اصلاً کلاس public نداشته باشد.

  7. ایجاد کردن کلاس‌های غیر public هم به تعداد صفر یا بیشتر ممکن است.

  8. متد‌های Getter و Setter بصورت Public تعریف می‌پذیرند.

  9. از همه کلاس‌ها قابل استفاده است



5.1.2)private

  1. نوعی سطوح دسترسی به متد و ویژگی‌ها

  2. سطح دسترسی private برای یک کلاس معنی ندارد(مگر برای کلاس داخلی یا همان inner Class ها)

  3. دسترسی به آن فقط از داخل همین کلاس ممکن است.

  4. معمولاً ویژگی‌ها (property) بصورت private تعریف می‌شوند و برای تغییر در ویژگی‌ها از متدهای Setter و برای دریافت مقدار ویژگی‌ها از متدهای getter استفاده می‌شود.

  5. دلیل استفاده از getter , setter این است که :

    1. اعتبار سنجی: اجازه هر مقداری را ندهیم:

public void setAge(ini a) {

if (a>0 && a<150)

age=a;

}



5.1.3)Protected

  1. ویژگی در داخل زیرکلاس‌ها (وراثت) قابل استفاده است ولی در سایر کلاس‌ها مخفی بماند و قابل استفاده نیست.

  2. برای ویژگی‌ها و متدها قابل تعیین است.

  3. اگر یک عضو (متد یا متغیر) را Protected کنیم آنگاه برای زیر کلاس در دسترس است.

  4. اعضای protected برای کلاس‌های داخل همان بسته هم قابل استفاده هستند

  5. برای سایر کلاس‌ها که زیرکلاس کلاس اصلی‌مان نیستند و یا در بسته قرار ندارند ویژگیها مخفی خواهد بود و انگار private خواهد بود

  6. سطح دسترسی کمتر از Public و بیشتر از package Access







5.1.4)Package Access

حالت پیش‌فرض و درصورت عدم تعیین سطح دسترسی، دسترسی به آن فقط در داخل کلاس‌های همین بسته ممکن است.











فصل 6) Java Virtual Machine (JVM)

هربرنامه در جاوا بر روی JVM اجرا می‌شود

نکته: در قطعه کد زیر موارد اشاره شده در حافظه‌های متناظر قرار می‌گیرند:

public static void swapNames(Students s1, Students s2) {

String tmp = s1.name;

s1.name = s2.name;

s2.name = tmp;

int numbers = 5;

}

حافظه Stack متغیرهایی نظیر number و tmp و s2 و s1 را در خود جای می‌دهد که متغیر number مقدار نگهداری می‌کند ولی موارد دیگر آدرس(شیء) را نگهداری می‌کنند

حافظه Heap مو اردی نظیر : آدرس جایی که number و tmp و s2 و s1 دارند به آن اشاره میکنند







6.1) Heap

همه اشیاء در بخشی از حافظه بنام Heap در رم ذخیره می‌شود

عملگر new حافظه را در بخشی بنام Heap ایجاد می‌کند.



6.1.1)Garbage Collection

  1. فقط برای Heap وجود دارد و برای استک این موضوع کاربرد ندارد

  2. Garbage Collector بدون نیاز به دخالت برنامه نویس قابلیت پاکسازی حافظه را دارد.

  3. این موجودیت که بخشی از jvm می‌باشد،‌ بصورت خودکار اشیاءی که دیگر در برنامه استفاده نمی‌شوند را شناسایی کرده و حافظه آن را آزاد می‌نماید(حافظه Heap) وآن اشیاء مرده را دور می‌ریزد. تا حافظه برای نگهداری اشیاء جدید خالی باشد.

  4. زباله روب یا همان Garbage Collection فقط درباره حافظه هست. و نمی‌تواند منابعی مثل فایل را که توسط یک شیء باز شده است را آزاد سازی نماید.



6.1.2)تعیین فضای حافظه

برای تعیین اندازه اولیه Heap از عبارت Xms استفاده می‌شود.

برای تعیین حداکثر اندازهHeap از عبارت Xmx استفاده می‌شود.

بطور مثال:

java person

java -Xms512m -Xmx375m Person

java -Xss4m Test

Java -Xmx3750m -Xss4m Main

نکته: اگر برنامه‌ای اشیاء فراوانی را new نماید ممکن است با ارور Java Heap Space روبرو شویم یعنی یک ارور از نوع:

OutOfMemoryError: Java heap space



6.2) Stack

متغیرهای محلی هر متد در این حافظه قرار خواهند گرفت

وقتی یک متد فراخوانی می‌شود به تعداد متغیرهای محلی آن در Stack فضا اشغال می‌شود و وقتی این متد تمام شد حافظه های اختصاص داده شده آزاد خواهد شد

برای تعیین حداکثر اندازهStack از عبارت Xss استفاده می‌شود.



نکته: اگر یک متد را بصورت بازگشتی صدا بزنیم طوریکه هیچ شرط پایانی نداشته باشد، آنگاه با ارور Stack Overflow روبرو خواهیم شد

int Func(int i){

return Func(i+1);

}



6.3) ClassPath

  1. یک پارامتر برای کامپایلر جاوا یا JVM هست.

  2. مشخص می‌کند در چه محل‌هایی به دنبال کلاس‌ها و بسته‌ها بگردند

  3. این پارامتر به دستور java یا javac پاس می‌شود- یا اینکه بصورت یک متغیر محیطی EnvironmentVariable تعریف می‌شود

  4. همچنین محل کلاس‌های موجود در زبان جاوا نیازی به معرفی در ClassPath ندارند مثل String

  5. با مفوم path اشتباه نگیرید-path مربوط به سیستم عامل است و محل فایل‌های اجرایی را مشخص می‌کند

  6. با مفهوم Working Directory اشتباه نگیرید(دایرکتوری که برنامه در آن مسیر دارد اجرا می‌شود)



در ویندوز:

java -cp D:\myprogram org.mypackage.HellowWorld

در لینوکس:

java -cp /home/user/myprogram org.mypackage.HellowWorld

یعنی کلاس‌های ما در مسیر /home/user/myprogram قرار دارند و اسم کامل کلاس هم org.mypackage.HellowWorld نام دارد.

  1. میتوان از متغیر محیطی استفاده کرد:

set CLASSPATH=D:\myprogram

java org.mypackage.HelloWorld

  1. تعیین چندین فولدر یا JAR در مسیر classpath:

java -cp D:\myprogram;d:\lib\support.jar org.mypackage.HellowWorld

  1. برای جداکردن بخش‌های مختلف cp در لینوکس از کاراکتر : و در ویندوز از کاراکتر ; استفاده می‌شود.

  2. عبارت خط cp- معادلclasspath- است.

  3. استفاده از چندین فایل JAR و شاخه جاری به عنوان cp:

java -classpath ‘.:/mylib/*’ MyApp





6.4) MetaSpace و PermGen(Permanent Generation)

  1. هر «شیء کلاس» در حافظه جای می‌گیرد. بخشی از حافظه مسئول نگهداری این اشیاء است

  2. قبل از نسخه ۸ جاوا اطلاعات کلاس‌ها (شیء کلاس) د ربخشی بنام PermGen دخیره می‌شد

  3. اگر پروژه بسیار بزرگ داشته باشیم ممکن است این فضا پر شود و با خطای OutOfMemoryError مواجه شویم(برنامه‌ای که کلاس‌های زیادی شامل کتابخانه‌ها و فایل‌های Jar متنوع باشد)

  4. حجم حافظه PermGen قابل تنظیم است

‫‪java‬‬ ‫‪-XX:MaxPermSize=512m‬‬ ‫‪MyClass‬‬

  1. بعد از جاوای8 اطلاعات مربوط به کلاس‌ها در MetaSpace نگهداری می‌شود و PermGen به کلی حذف شده است و دیگر نیازی به تنظیم اندازه PermGen نداریم.





فصل 7) مدیریت خطا (Exception)

  1. متدی که در آن ممکن است خطا یا Exception صورت بگیرد موظف هست تا در ابتدای خط خود عبارت throw Exception را اعلام نماید.

  2. .اگر یک متد بخواهد یک اکسپشن را مشخص نماید و گزارش وقوع خطا بدهد این کار را با کلیدواژه throw انجام میدهد.

public static int getYear(String day) throws Exception{

if (day == null || day.length() == 0)

throw new Exception("Bad Parameter");

String yearString = day.substring(0, 4);

int year = Integer.parseInt(yearString);

return year;

}

  1. قطعه کدی که در داخل بلاک try-catch نوشته بشود، اگر داخلش خطلایی رخ دهد اجزا قطع شده و به داخل catch خواهیم رفت

  2. throw یک استثناء پرتاب می‌کند

  3. throws اگر متدی احتمال دارد یک استثناء پرتاب کند باید آن را اعلان کند

public class Test1{

public ststic void main(String[] args){

try{

Scanner scanner = new Scanner(System.in);

int first = Scanner.nextInt();

int second = Scanner.nextInt();

int div = division(first,second);

System.out.println(div);

}catch (Exception e) {

System.out.println(e.getMessage());

}

}



private static int division(int first, int second) throws Exception {

if(second == 0)

throw new Exception(“OOPS! Markhraj Sefre!);

return first/second;

}



  1. هر استثناء یک شیء است «شیء استثناء»

  2. هر شیء دارای کلاس است(Type یا کلاس)

  3. در جاوا کلاس‌های مختلفی برای مدیریت استثناها و دسته‌بندی آن‌ها وجود دارد مثل: ClassCastException یا NullPointException

  4. می‌توانیم کلاس جدید از استثناء ایجاد کنیم: مثل IranianBadNationalIdException

مثال:

class MultipleCatch {

public static void main(String args[]) {

try {

int den = Integer.parseInt(args[0]);

System.out.println(3/den);

} catch (ArithmeticException e1) {

System.out.println("Divisor is zero");

} catch (ArrayIndexOutOfBoundsException e2) {

System.out.println("Missing argument");

}

System.out.println("After exception");

}

}



7.1) ایجاد کلاس Custom از یک اکسپشن

  1. کلاس باید زیرکلاس Exception باشد

  2. کلاسی با عنوان java.lang.Exception در جاوا وجود دارد

  3. زیرکلاس‌های Exception میتوانند throw پرتاب یا catch دریافت کنند

  4. معمولاً کلاس‌های ساده‌ای هستند

  5. متدها و متغیرهای کم و مختصری دارند

  6. معمولاً یک سازنده بدون پارامتر دارند

  7. یک پارامتر رشته دارند که پیغام خطا را مشخص می‌کند

public class IOException extends Exception {

public IOException() { super(); }

public IOException(String message) { super(message);}

...

}

  1. نحوه استفاده از کلاس IOException : بصورت زیر است:

if(...)

throw new IOException();

if(...)

throw new IOException("Internal state failure");



مثال از یک کلاس استثنای جدید:

class BadIranianNationalID extends Exception {}

. . .

. . .

try {

if (input.length()!=10) { throw new BadIranianNationalID();}

System.out.println("Accept NationalID.");

} catch (BadIranianNationalID e) {

System.out.println("Bad ID!");

}

مثال:

public static Integer getYear(String day) throws Exception {

if (day == null)

throw new NullPointerException();

if (day.length() == 0)

throw new EmptyValueException();

if (!matchesDateFormat(day))

throw new MalformedValueException();

String yearString = day.substring(0, 4);

int year = Integer.parseInt(yearString);

return year;

}

private static boolean matchesDateFormat(String input) {...}

  1. در یک try-catch اگر در یک بلاک catch یک نوع استثناء را دریافت کنیم نمی‌توانیم در یک catch بعدی زیرکلاس آن نوع استثناء را دریافت کنیم دراین صورت کامپایلر اعلام خطا می‌کند UnreachableCatchBlock

مثال:

‫‪try‬‬ ‫{‬

‫‪int‬‬ ‫‪a‬‬ ‫=‬ Integer.parseInt(args[0]);

‫‪int‬‬ ‫‪b ‫=‬ Integer.parseInt(args[1]);

‪System.out.println(a/b‬‬);

}‬ ‫‪catch‬‬ ‫‪(Exception‬‬ ex)‬‬ ‫{‬

‫‪//..‬‬

}‬ ‫‪catch‬‬ ‫‪(ArrayIndexOutOfBoundsException‬‬ e) ‫{‬

‫‪//..‬‬

}‬



  1. از جاوای 7 به بعد می‌توانیم کد را از شکل زیر به شکل اصلاح شده در آوریم:

try{

f();

}catch (IOException ex) {

log(ex);

}catch (SQLException ex) {

log(ex);

}catch (ClassCastException ex){

throw ex;

}

شکل اصلاح شده

try{

f();

}catch (IOException | SQLException ex) {

log(ex);

}catch (ClassCastException ex){

throw ex;

}

  1. قبل از جاوای ورژن7:

BufferedReader br = new BufferedReader(new FileReader(path));

try {

return br.readLine();

} finally {

if (br != null) br.close();

}

بعد از جاوای ورژن 7:

try (BufferedReader br =

new BufferedReader(new FileReader(path))) {

return br.readLine();

}



  1. استثناء را نادیده نگیرید-مثلا کد فوق SQLException را خفه میکند(کار خوبی نیست)

‫‪try‬‬ ‫{‬

db.save(entity‬‬);

}‬ ‫‪catch‬‬ ‫‪(SQLException ex) {}

  1. پیام مناسب و گویا به عنوان message استفاده کنید:

throw new IOException(message);

  1. در بسیاری از موارد باید بروز خطا را لاگ بزنیم و این کار در بلاک catch قابل انجام است-البته بهتر است از فناوری مخصوص لاگ مثل SLF4J استفاده نمایید. استفاده از System.out.println یا printStackTrace برای اینکار مناسب نیست

  2. مستند سازی مناسب رفتار استثناها در برنامه شما با کمک جاواداک

/**

‫‪...‬‬

*‬ ‫‪@throws‬‬ ‫‪PatternSyntaxException‬‬

*‬

‫‪if‬‬ ‫‪the‬‬ ‫‪regular‬‬ ‫‪expression's‬‬ ‫‪syntax‬‬ ‫‪is‬‬ ‫‪invalid‬‬

‫‪*/‬‬

‫‪public‬‬ ‫][‪String‬‬ ‫‪split(String‬‬ ‫)‪regex‬‬ ‫}‪{...‬‬















7.2) stack trace

  1. وقتی استثناء را دریافت می‌کنیم این اطلاعات در شیء استثناء موجود است:۱-محل اصلی پرتاب شدن استثناء ۲-مجموعه استک متدهایی که استثناء از آن‌ها رد شده است که به مجموعه این اطلاعات stack trace گفته می‌شود.

  2. برخی متدهای دستیابی به stack trace از طریق شیء استثناء:

printStackTrace();

getStackTrace();

مثال:

public class StackTrace {

public static void main(String[] args) {

try{ f();}

catch(Exception e){e.printStackTrace();}

}

private static void f() {g();}

private static void g() {throw new NullPointerException();}

}

که مثال بالا خروجی خطای زیر را برمیگرداند:

java.lang.NullPointerException

at Third.g(Third.java:18)

at Third.f(Third.java:13)

at Third.main(Third.java:5)



7.3) finaly

‫‪try‬‬ ‫{‬

‫‪//..‬‬

}‬ ‫‪catch‬‬ ‫‪(ExceptionType‬‬ ‫)‪e‬‬ ‫{‬

...‪//‬‬

}‬ ‫‪finally‬‬ ‫{‬

...‪//‬‬

}‬

  1. در انتهای اجزای try-catch حتماً اجرا می‌شود

  2. اگر خطا پرتاب شود یا نشود در انتهای کار ازای بخش finaly تضمین می‌شود

  3. این بلاک حتماً اجرا می‌شود در هر شرایطی

  4. این بلاک معمولاً برای آزادسازی منابع گرفته شده در Try مناسب است-همانند بستن فایل یا اتمام اتصال به دیتابیس البته هر منبعی بجز حافظه که این حافظه توسط ذباله روب بصورت خودکار آزاد می‌شود.





7.4) کلاس throwable

  1. درواقع هر آنچه درمورد Exception گفته شده است درباره Throwable هم صادق است

  2. دونوع Throwable داریم:۱-Exception ها که مفصل صحبت شده است ۲-Error یا همان خطا که معمولاا تلاش نمیکنیم که آن‌ها را در برنامه catch کنیم – حتی اگر آن را catch کنیم کارمهمی درقبال این خطاها نمی‌توانیم انجام دهیم مانند OutOfMemoryError

  3. برای برخی از استثنا‌ها مثل ArithmeticException ذکر throws واجب نیست اگر واجب بود هرمتدی که عملگر تقسیم ریاضی داشت باید throws را ذکر میکرد و دراینصورت throws ها نامهم میشدند







7.5) استثناهای چک شده(CheckedException)

برنامه‌ باید استثنای پیش آمده را دریافت کند و یا احتمال پرتاب شدن آن را اعلام کند وگرنه خطای کامپایلر رخ میدهد





7.6) استثناهای چک نشده(UnCheckedException)

  1. کامپایلر دریافت یا اعلان پرتاب را اجبار نمی‌کند و در زمان کامپایل چک نمی‌شود

  2. چک نشده یعنی توسط کامپایلر چک نشده و در کد حتماً چک خواهد شد

  3. کلاس‌هایی مثل کلاس Error یا کلاس RuntimeException یا زیرکلاس‌های Error یا RuntimeException

قطعه کد زیر ارور میدهد:

void example(int x) {

if(x==1)

throw new Error();

if(x==2)

throw new RuntimeException();

if(x==3)

throw new NullPointerException();

if(x==3)

throw new IOException(); //اینجا ارور میدهد Syntax Error:Unhandled Exception Type IOException

فرم درست این قطعه کد بصورت زیر است زیرا

void example(int x) throws IOException {

...

if(x==3)

throw new IOException();

}





7.7) استثناء و ارث‌بری

‫‪class‬‬ Parent {

void f()‬ {. . . }‬

}

‫‪class‬‬ ‫‪Child‬‬ ‫‪extends‬‬ ‫Parent {

‫‪void f() {. . .}

}‬

فرض کنید متد f در زیرکلاس override شده باشد-در این صورت این متد در زیرکلاس نمی‌تواند استثناهای بیشتری از f در اَبَرکلاس پرتاب کند و انواع استثناء که در متدی در زیر کلاس پرتاب می‌شوند باید کمتر یا مساوری تعریف آن متد در اَبَرکلاس باشد(منظور استثناهایی است که با ذکر throws مشخص شوند) وگرنه کامپایلر جلوگیری کرده و ارور می‌گیرد







فصل 8) Collections

در آرایه محدودیت‌هایی هست هندل کردن آن کمی سخت است مانند:: افزایش طول سایز آرایه (Size). حذف برخی عناصر آرایه





8.1) ArrayList

  1. در مسیر java.ustil.ArrayList قرار دارد

  2. همانند آرایه ای که امکان تغییر اندازه در آن وجود دارد

  3. در ابتدا خالی است و به مرور می‌توانیم عناصر به این فهرست اضافه یا کم کنیم

  4. در مثال زیر شیء students ظرفی از اشیاء هست که هر نوع از اشیاء را میتوان به آن اضافه کرد.(معمولا نیازمندی به این صورت است که همه اجزای یک لیست دارای جنس مشابه باشند)

‫‪ArrayList‬‬ ‫‪students‬‬ ‫=‬ ‫‪new‬‬ ArrayList();

‫‪students.add(new‬‬ ‫‪Student("Ali‬‬ ‫Alavi”));

‫‪students.add(new‬‬ ‫‪Student("Taghi‬‬ ‫Taghavi”));

students.remove(0‬‬);

مثال:

‫‪ArrayList‬‬ ‫‪s‬‬ ‫=‬ ‫‪new‬‬ ‫ ArrayList();

‫‪s.add(new‬‬ ‫‪Student("Ali ‪Alavi‬‬”));

‫‪s.add("Taghi ‪Taghavi‬‬”));

‫‪s.add(new‬‬ Object());‪

  1. لیست‌ها میتوانند نوع اشیاء درون خود را مشخص کنند:

ArrayList<Student> students = new ArrayList<Student>();

مثال:

ArrayList<Student> students = new ArrayList<Student>();

students.add(new Student("Ali Alavi"));

students.add(new Student("Taghi Taghavi"));

students.remove(0);

students.remove(new Student("Ali Alavi"));

Student student = students.get(0);

System.out.println(student);

مثال:

ArrayList<String> names = new ArrayList<String>();

names.add("Ali Alavi");

names.add("Taghi Taghavi");

names.remove(0);

names.remove("Ali Alavi");

String name = names.get(0);

System.out.println(name);

  1. برخی متدهای مهم این کلاس:

  1. کلاس ArrayList واسط java.util.List را پیاده‌سازی کرده است. متدهای فوق همگی در واسط(interface) List تعیین شده‌اند

مثال:

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

Scanner scanner = new Scanner(System.in);

while(true){

String input = scanner.next();

if(input.equalsIgnoreCase("exit"))

break;

list.add(input);

}

if(list.isEmpty()){

System.out.println("No string entered");

}else{

System.out.println(list.size());

if(list.contains("Ali"))

System.out.println("Ali Found!");



for (String s : list) {

System.out.println(s);

}

}

  1. نگاهی به interface با نام List:

interface List<E> {

int size();

boolean isEmpty();

boolean contains(Object o);

boolean add(E e);

boolean remove(Object o);

void clear();

E get(int index);

E set(int index, E element);

void add(int index, E element);

E remove(int index);

int indexOf(Object o);

int lastIndexOf(Object o);

List<E> subList(int fromIndex, int toIndex);

}

  1. ArrayList ظرفی از اشیاء است: هر یک از مقادیر داخل آن، یک شیء است

  2. انواع داده اولیه (primitive types) نمی‌توانند در ArrayList قرار گیرند. این محدودیت برای سایر انواع ظرف‌ها (مثل LinkedList و Set و ...) هم وجود دارد. در واقع این محدودیت برای همه انواع عام (generics)، از جمله ظرف‌ها، وجود دارد. این محدودیت برای آرایه وجود ندارد. مثلاً خط زیر غیرممکن است ولی خط دوم ممکن است:

ArrayList<int> // غلط

int[] //درست

  1. درواقع ArrayList لیستی هست که به کمک آرایه پیاده‌سازی شده است.

  2. برای حذف یک عضو ArrayList ، خانه‌های بعدی در خانه قبلی کپی می‌شوند.

  3. گاهی آرایه و گاهی ArrayList بهتر است.

  4. مزایای آرایه:امکان استفاده از انواع داده اولیه (مثل int و double)-آرایه می‌تواند کارایی (performance) بیشتری داشته باشد

  5. مزایای ArrayList :ارائه متدها و امکاناتی که در آرایه نیست. مانند اضافه و کم کردن اعضا به صورت پویا، جستجو در لیست و …

8.1.1) تبدیل آرایه به ArrayList

String[] strings = {"ali", "taghi"};

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

for (String str : strings)

list.add(str);

8.1.2)تبدیل ArrayList به آرایه:

String[] array = new String[list.size()];

for (int i = 0; i < array.length; i++)

array[i] = list.get(i);



8.1.3)تبدیل Collection به آرایه

واسط Collection دو متد با نام toArray برای تبدیل به آرایه معرفی می‌کند:

8.1.3.1)روش اول

با استفاده از متد زیر:

Object[ ] toArray()

  1. این متد پارامتری نمی‌گیرد

  2. فهرست را به یک آرایه از Object‌ها تبدیل می‌کند

  3. بدین ترتیب نوع واقعی اشیاء در آرایه معلوم نیست



8.1.3.2)روش دوم

با استفاده از متد زیر:

T[] toArray(T[] a)

  1. در این روش، آرایه‌ای از اشیاء به عنوان پارامتر ارسال می‌شود

  2. مقدار برگشتی از نوع داده مشخص شده است

  3. اگر پارامتر موردنظر به اندازه کافی فضا داشته باشد، همان را پر می‌کند وگرنه، یک آرایه جدید از همان جنس می‌سازد



مثال:



ArrayList<Integer> list = new ArrayList<Integer>();

list.add(new Integer(5));

list.add(new Integer(4));

list.add(new Integer(3));



Object[] array = list.toArray();

for (Object object : array) {

Integer i = (Integer) object;

System.out.println(i);

}



Integer[] array2 = list.toArray(new Integer[list.size()]);

for (Integer i : array2)

System.out.println(i);

Integer[] array3 = list.toArray(new Integer[0]);

for (Integer i : array3)

System.out.println(i);







8.2) لیست پیوندی(LinkedList)

  1. یست پیوندی یک ساختمان داده است (data structure) که در آن، برخلاف آرایه، همه اعضا پشت سرهم در حافظه قرار نمی‌گیرند. بلکه هر عضو فهرست، محل (آدرس یا ارجاع) عضو بعدی را نگه می‌دارد

  2. برای اضافه کردن یک عضو به فهرست: یک شیء جدید ایجاد می‌شود و آخرین ارجاع (اشاره‌گر) به این شیء جدید اشاره خواهد کرد , برای حذف یک عضو از فهرست: کافیست اشاره‌گر به این شیء، به شیء بعدی اشاره کند

  3. کلاس java.util.LinkedList در جاوا پیاده‌سازی شده است

  4. کلاس LinkedList هم مانند ArrayList واسط List را پیاده‌سازی کرده است

  5. همه متدهای مهم List را دارد، مانند add ، get ، remove و … بنابراین نحوه کاربرد LinkedList مشابه ArrayList است

LinkedList<Double> grades = new LinkedList<Double>();

grades.add(new Double(18.5));

grades.add(new Double(19.5));

grades.add(new Double(17.5));

for (Double d : grades)

System.out.println(d);

مثال از لیست پیوندی:

List<String> list = new LinkedList<String>();

list.add("Ali");

list.add("Taghi");

System.out.println(list.get(1));

list.remove("Taghi");

for (String string : list) {

System.out.println(string);

}



  1. کلاس‌هایLinkedList و ArrayList واسط List را پیاده کرده‌اند اما پیاده‌سازی متفاوتی دارند: درون هر LinkedList یک آرایه نیست، یک لیست پیوندی است. در مجموع، کلاس ArrayList پرکاربردتر است .البته در برخی موارد، استفاده از LinkedList کاراتر است.

  2. در زمانی که تعداد زیادی add و remove در لیست داریم بهتر است از لیست پیوندی استفاده شود

  3. درهنگامی که دسترسی فراوان به عناصر(بااستفاده از اندیس) وجود دارد بهتر است لیستمون را با کمک ArrayList پیاده‌سازی کنیم. هزینه اجرای get(i) در ArrayList کم است ولی در لیست پیوندی i عنصر باید پیمایش شوند تا به عنصری با اندیس i برسیم.

  4. در کد زیر بهتر است بخاطر ارجاع‌های مکرر از لیست پیوندی استفاده شود تا سریعتر اجرا شود

for(int i=0;i<1000000;i++){

for(int j=0;j<100;j++)

list.add(0, new Object());

for(int j=0;j<100;j++)

list.remove(0);

}



8.3) مجموعه یا Set [HashSet]

  1. شبیه معنای «مجموعه» در ریاضیات است. تعدادی شیء متمایز که لزوماً بین اعضا ترتیبی وجود ندارد مثلاً دو مجموعه زیر با هم برابر هستند

{1,2,3,1,4,2} = {4,3,2,1}

  1. مجموعه (Set) یک واسط در جاوا است: java.util.Set

  2. کلاس‌ HashSet در جاوا واسط Set را پیاده‌سازی کرده است. مثال:

HashSet<String> set= new HashSet<String>();

set.add("Ali");

set.add("Taghi");

set.add("Naghi");

مثال:

Set<String> set = new HashSet<String>();

set.add("Ali");

set.add("Taghi");

set.add("Taghi");

set.add("Ali");

set.add("Taghi");

System.out.println(set.size());

for (String str : set)

System.out.println(str);

set.remove("Ali");

System.out.println(set.contains("Ali"));

System.out.println(set.contains("Taghi"));

set.clear();

System.out.println(set.size());



8.3.1)تفاوت اصلی set و List

  1. اشیاء داخل یک Set متمایز هستند، شیء تکراری در Set وجود ندارد

  2. اگر شیئی تکراری به مجموعه اضافه شود، شیء قدیمی حذف می‌شود

  3. اعضای List ترتیب دارند. بین اعضای Set لزوماً ترتیبی وجود ندارد

  4. واسط Set هیج متدی که با اندیس کار کند، ندارد

  5. مثلاً در واسط Set ، متد get(i) نداریم، ولی در List داریم

  6. متدهای دیگری مثل موارد زیر هم در Set وجود ندارد:

set(int index, E element)

int indexOf(Object o)

int lastIndexOf(Object o)

remove(int index)





8.3.2)برتری مجموعه یا لیست

  1. در برخی کاربردها List و در برخی دیگر Set مناسب‌تر است

  2. List دسترسی به اعضا از طریق اندیس را ممکن می‌کند

  3. Set اجازه افزودن عضو تکراری به مجموعه را نمی‌دهد

  4. تکراری بودن عضو جدید را چک می‌کند (سربار محاسباتی)

  5. می‌تواند از هدر رفتن حافظه جلوگیری کند (کاهش حافظه مصرفی)

  6. سؤال کلیدی: آیا در فهرست موردنظر، عضو تکراری مجاز است؟ اگر بله: List بهتر است، وگرنه Set بهتر است. مثال: فهرست شماره دانشجویی اعضای یک دانشگاه: Set بهتر است-[فهرست نمرات یک درس: List بهتر است (نمره تکراری ممکن است)]

  7. List و Set زیرواسط Collection هستند





8.4) Map

  1. یک واسط با نام java.util.Map وجود دارد که یک Collection نیست

  2. یک Map مانند یک جدول یا نگاشت از اشیاء عمل می‌کند

  3. همانند جدولی که دو ستون دارد (هر سطر یک زوج مرتب) ، ستون اول را کلید (Key) و ستون دوم را مقدار (Value) می‌گویند

  4. اعضای ستون اول (کلیدها) یکتا هستند: کلید تکراری نداریم

  5. اعضای ستون دوم (مقادیر) ممکن است تکراری باشند

  6. نوع ستون اول و ستون دوم قابل تعیین است

  7. مثال: یک map شامل نمرات دانشجویان:(جدول یا نگاشتی از رشته‌ها به اعداد حقیقی)-کلید آن (ستون اول) رشته‌ها و مقادیر آن (ستون دوم) اعداد حقیقی هستند (نگاشتی از رشته به عدد حقیقی)

Map<String, Double> map

  1. مثال زیر، نگاشتی از عدد صحیح به دانشجو

Map<Integer, Student>

  1. هر نوع شیئی به عنوان کلید یا مقدار، قابل استفاده است

  2. انواع داده اولیه مثل int و double در هیچ‌یک از ظرف‌های جاوا قابل‌استفاده نیستند

  3. Map یک واسط است،

  4. یکی از کلاس‌هایی که Map را پیاده‌سازی‌کرده: java.util.HashMap

Map<Integer, String> map = new HashMap<Integer, String>();

map.put(87300876, "Ali Alavi");

map.put(87234431, "Taghi Taghavi");

map.put(87300876, "Naghi Naghavi");

String name = map.get(87300876);

System.out.println(name);

System.out.println(map.get(87234431));

[در کد بالا به جای Integer از int استفاده شده است]-[تبدیل int به Integer به صورت خودکار انجام می‌شود (auto-boxing)]-[

(از جاوا 5 به بعد)]

  1. نوع مورد استفاده در همه کلاس‌های java collections framework باید شیء باشند



8.4.1)نگاهی به واسط Map

public interface Map<K,V> {

V get(Object key);

V put(K key, V value);

int size();

boolean isEmpty();

boolean containsKey(Object key);

boolean containsValue(Object value);

V remove(Object key);

void putAll(Map m);

void clear();

Set<K> keySet();

Collection<V> values();

}



8.4.2)put

  1. تغییر مقدار با کمک put صورت می‌گیرد

  2. اگر سطری با کلید تکراری به یک map اضافه شود: مقدار قبلی آن کلید حذف می‌شود. مثال:

Map<Integer, String> map = new HashMap<Integer, String>();

map.put(76, “Ali”)

map.put(31, “Taghi”)

map.put(76, “Naghi”)

  1. این برنامه به شرطی درست کار می‌کند که متدهای equals و hashCode به خوبی در کلاس Student پیاده‌سازی شده‌باشند

Map<Student, Double> map = new HashMap<Student, Double>();

map.put(new Student("Ali Alavi"), new Double(18.76));

map.put(new Student("Taghi Taghavi"), new Double(15.43));

map.put(new Student("Naghi Naghavi"), new Double(17.26));

map.put(new Student("Naghi Naghavi"), new Double(15.26));

map.remove(new Student("Naghi Naghavi"));



Double grade = map.get(new Student("Taghi Taghavi"));

System.out.println("Grade of Taghi=" + grade);



for (Student student : map.keySet())

System.out.println(student.toString());



Double totalSum = 0.0;

for (Double avg : map.values())

totalSum += avg;



System.out.println("Average = " + (totalSum / map.size()));





8.5) کلاس‌های Arrays و Collections

  1. جاوا دو کلاس، با متدهای کمکی مفید برای کار با آرایه‌ها و Collection‌ها ارائه کرده است

  2. کلاس java.util.Arrays برای کار با آرایه‌ها

  3. کلاس java.util.Collections برای کار با Collection ها

  4. این کلاس‌ها دارای متدهای استاتیک متنوعی هستند، برای:

  5. کپی اشیاء درون آرایه یا ظرف

  6. پر کردن همه اعضا با یک مقدار مشخص (fill)

  7. جستجو (search)

  8. مرتب‌سازی (sort)

  9. و ...



8.5.1)برای کاربرد Arrays

Random random = new Random();

Long[] array = new Long[100];

Arrays.fill(array, 5L);

Long[] copy = Arrays.copyOf(array, 200);

for (int i = 100; i < copy.length; i++)

copy[i] = random.nextLong()%10;

//An unmodifiable list:

List<Integer> asList = Arrays.asList(1, 2 , 3, 4);

List<Long> asList2 = Arrays.asList(array);

Arrays.sort(array);

int index = Arrays.binarySearch(array, 7L);

int[] a1 = {1,2,3,4};

int[] a2 = {1,2,3,4};

System.out.println(a1==a2);

System.out.println(a1.equals(a2));

System.out.println(Arrays.equals(a1, a2));

System.out.println(a1);

System.out.println(a1.toString());

System.out.println(Arrays.toString(a1));



8.5.2)مثال برای کاربرد Collections

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

Collections.addAll(list, "A", "Book", "Car", "A");

int freq = Collections.frequency(list, "A");

Collections.sort(list);

Comparator<String> comp = new Comparator<String>(){

public int compare(String o1, String o2) {

return o1.length() < o2.length() ? -1 :

(o1.length() == o2.length() ? 0 : +1);

}

};

Collections.sort(list, comp);

Collections.reverse(list);



String min = Collections.min(list);

String max = Collections.max(list);

String max2 = Collections.max(list, comp);



Collections.shuffle(list);



Collections.fill(list, "B");



8.6) مرور برخی واسط‌ها و کلاس‌های مهم دیگر



توضیح

پدر

نوع

نام

یک مجموعه مرتب

Set

واسط

SortedSet

یک مجموعه مرتب که براساس یک درخت پیاده شده

SortedSet

کلاس

TreeSet

یک نگاشت (جدول) که بر اساس کلیدهایش مرتب است

Map

واسط

SortedMap

نگاشت مرتبی (براساس کلید) که با درخت پیاده شده

SortedMap

کلاس

TreeMap

یک صف از اشیاء (FIFO)

Collection

واسط

Queue

یک صف اولویت‌دار (بر اساس مقایسه و ترتیب اشیاء)

Queue

کلاس

PriorityQueue

یک پشته از اشیاء (LIFO)

Vector

کلاس

Stack



8.6.1)اشاره به برخی مفاهیم



  1. برخی از ظرف‌ها synchronized هستند (Synchronized Collections)

  2. ظرف‌هایی که استفاده از آن‌ها در چند thread همزمان، امن است مثل کلاس‌های thread-safe (مراجعه به مبحث thread)-مثل Vector و ConcurrentHashMap

  3. اگر نیازی به استفاده همزمان از اشیاء کلاس نیست، از اینها استفاده نکنید

  4. برخی ظرف‌ها غیرقابل تغییر هستند (Unmodifiable Collections)

  5. فقط می‌توانیم اعضای آن‌ها را پیشمایش کنیم (کم‌و‌زیاد کردن اعضا ممکن نیست)

مثال:

List<String> unmod1 = Arrays.asList("A", "B");

List<String> mod1 = new ArrayList<>(unmod1);

Collection<String> unmod2 = Collections.unmodifiableCollection(mod1);

  1. امکان عدم ذکر نوع عام (generic) هنگام ایجاد شیء(از جاوا 7 به بعد):

List<String> mylist1 = new ArrayList<String>();

List<String> mylist2 = new ArrayList<>();



Set<Integer> set1 = new HashSet<Integer>();

Set<Integer> set2 = new HashSet<>();



Map<String, Integer> m2 = new HashMap<String, Integer>();

Map<String, Integer> m1 = new HashMap<>();



















فصل 9) فایل

  1. تعریف فایل: مجموعه‌ای از بایت‌ها که در حافظه جانبی ذخیره شده‌اند

  2. انواع فایل بر اساس ذخیره سازی: : فایل متنی(کوچکترین واحد سازنده آن کاراکترها مانند فایل‌های html و xml و txt) و فایل باینری(واحد های سازنده آن بایت است مانند docx و pdf و zip و exe و غیره

  3. جاوا از استاندارد Unicode برای کاراکترها پشتیبانی می‌کند

  4. استانداردهای قدیمی‌تر مانندASCII محدود بود و کاراکترهایی مثل حروف فارسی و ژاپنی در ASCII پشتیبانی نمی‌شود

  5. استاندارد Unicode یک مجموعه کاراکتر (character set یا charset) است

  6. هر کاراکتر، به صورت یک عدد در کامپیوتر ذخیره می‌شود

  7. نحوه تبدیل کاراکتر به عدد توسط روش‌های کدگذاری (encoding) تعیین می‌شود

  8. روش‌های کدگذاری مختلفی برای یونیکد ارائه شده است، مانند UTF-8 ، UTF-16 و UTF-32

  9. جاوا از کدگذاریUTF-16 استفاده می‌کند (البته کدگذاری‌های دیگر هم پشتیبانی می‌شود)

  10. هر کاراکتر در UTF-16 معمولاً در دو بایت ذخیره می‌شود

  11. در قدیم، روش‌های کدگذاری دیگری (غیریونیکد) رایج بودند، مثل Windows-1256

  12. بیشتر سیستم‌های عامل ازکاراکتر / برای جدا کردن فولدرها استفاده می‌کنند. مثال:

/home/ali/file.txt

  1. اما در سیستم‌عامل ویندوز ازکاراکتر \ برای جدا کردن فولدرها استفاده می‌شود. مثال:

c:\textfiles\newfile.txt

  1. از طرف دیگر، کاراکتر \ در جاوا یک کاراکتر خاص (escape character) است

  2. در تعیین نام فایل یا فولدر در ویندوز:

مثلاً این آدرس

new File ("c:\textfiles\newfile.txt");

یعنی:

c:{tab}extfiles{newline}ewfile.txt

راه‌حل:

"c:\\textfiles\\newfile.txt" و یا "c:/textfiles/newfile.txt"









9.1) stream

  1. جریان اطلاعات به داخل برنامه یا خارج از یک برنامه، مانند: ذخیره و بازیابی از فایل-ارسال اطلاعات از طریق شبکه-تبادل داده با دستگاه‌های جانبی (مثلاً اسکنر) و ...

  2. کتابخانه java.io کلاس‌های متنوعی برای کار با فایل‌ها و جریان‌ها دارد

  3. جریان ورودی به برنامه (آن‌چه برنامه می‌خواند) : Input Stream

  4. جریان خروجی از برنامه (آن‌چه برنامه تولید می‌کند) : Output Stream

  5. ورودی و خروجی‌های متنی (جریان متنی):جریانی از کاراکترها

    1. امکانات جاوا برای این منظور: کلاس‌های Reader و Writer

    2. مثال: خواندن/نوشتن یک فایل txt یا تبادل متن تحت شبکه (مثلاً برنامه چَت)

  6. ورودی و خروجی‌های باینری (جریان باینری):جریانی از بایت‌ها

    1. امکانات جاوا: کلاس‌های InputStream و OutputStream

    2. مثال: برای خواندن و نوشتن یک فایل zip یا pdf

  7. در جاوا کلاس‌هایی برای کار با جریان داده (Stream) داریم:

    1. کلاس InputStream برای خواندن از جریان داده

    2. کلاس OutputStream برای نوشتن در جریان داده

  8. هر شیء از این کلاس‌ها به یک جریان داده متصل می‌شود

  9. مثال‌هایی از یک جریان داده:

    1. فایل، تبادل اطلاعات در بستر شبکه، تبادل اطلاعات با یک دستگاه جانبی (مثل اسکنر)

    2. ورودی و خروجی استاندارد:

  10. Syntax آن به شکل زیر است:

InputStream is = System.in;

OutputStream os = System.out;









9.2) بستن منبع

  1. بسياری از کلاس‌های مربوط به کار با فایل‌ها و جریان داده‌ها متد close() دارند

  2. در انتهای کار با شیء، باید شیء مربوطه close شود. وگرنه، برنامه منابعی گرفته که آزاد نکرده است

  3. مثلاً باز شدن و بسته شدن فایل: از طریق سیستم‌عامل و سیستم‌فایل انجام می‌شود.

  4. فایل باز: یک منبع (resource) از طرف سیستم‌عامل که به برنامه تخصیص داده شده

  5. این منبع، باید از طریق متد close() آزاد شود

  6. اگر آن را نبندیم، یک منبع از سیستم عامل گرفته‌ایم که آزاد نشده است

  7. فایل، یک منبع است که باید بعد از باز شدن و در انتهای کار با آن، آزاد شود. وگرنه:تعداد فایل‌های قابل باز کردن محدود است، امکان باز کردن آن فایل در برنامه‌های دیگر کمتر می‌شود و … مهمترین منبعی که برنامه‌ها می‌گیرند: حافظه است که مثلاً با کمک عملگر new حافظه تخصیص داده می‌شود

  8. آزادسازی حافظه به صورت خودکار توسط زباله‌روب انجام می‌شود

  9. برنامه‌ها منابع دیگری هم می‌گیرند مانند فایل‌هایی که باز می‌کنند یا سایر جریان‌ها (strream)

  10. برنامه‌نویس موظف است این منابع را آزاد کند (با کمک متد close)

  11. آزادسازی این منابع به صورت خودکار انجام نمی‌شود





9.3) کلاس FileReader

  1. کلاس Reader یک کلاس انتزاعی (abstract class) است

  2. کلاس FileReader یکی از زیرکلاس‌هایReader است

  3. برای خواندن از "فایل متنی" به کار می‌رود

  4. برای مطالعه Reader از کلاس FileReader مثال می‌زنیم:

FileReader inf = new FileReader("readme.txt");

int chCode;

while(-1 != (chCode=inf.read()) )

System.out.println("Next:"+(char)chCode);

inf.close();

  1. چرا Reader.read() یک int برمی‌گرداند، نه یک char ؟ پاسخ: برای تشخیص پایان فایل (با -1 مشخص می‌شود)

  2. ایجاد شیء:

FileReader fr = new FileReader(file_location);

  1. با ایجاد شیء، فایل موردنظر برای خواندن متن باز می‌شود (open)

  2. خواندن یک کاراکتر: متد read()

  3. بستن فایل: متد close()

  4. اما معمولاً فایل متنی را کاراکتر-کاراکتر نمی‌خوانیم

  5. معمولاً از متد read() استفاده نمی‌شود

  6. متدهای دیگری برای خواندن حجم بیشتری از اطلاعات وجود دارد. مثال: (تعداد کاراکترهایی که خوانده‌شده را برمی‌گرداند)

int read(char[ ] cbuf)







9.4) کلاس FileWriter

  1. کلاس Writerیک کلاس انتزاعی (abstract class) است

  2. کلاس FileWriter یکی از زیرکلاس‌های Writer است که برای نوشتن در "فایل متنی" به کار می‌رود. مثال:



FileWriter writer = new FileWriter("writeme.txt");

writer.write("This is a line. \n");

writer.write("This is the second line. \n");

writer.close();



  1. در صورت وجود فایل موردنظر، محتوای آن پاک می‌شود. در غیر این صورت، فایل موردنظر ایجاد می‌شود

  2. برای اضافه کردن به انتهای یک فایل موجود (append)، آن را این‌گونه ایجاد کنید:

FileWriter wr = new FileWriter("text.txt", true);



9.5) کلاس FileInputStream

کلاس FileInputStream برای خواندن از فایل‌:

FileInputStream extends InputStream

مثال:

List<Byte> list = new ArrayList<>();

FileInputStream inf = null;

try{

inf = new FileInputStream("file");

int bCode;

while(-1 != (bCode=inf.read()) )

list.add((byte)bCode);

}finally{

if(inf!=null)

inf.close();

}





9.6) کلاس FileOutputStream

کلاس FileOutputStream برای نوشتن در فایل‌:

FileOutputStream extends OutputStream

مثال:

int[] numbers = {1234567890, 1234567891, 1234567892};

byte[] array = intToByteArray(numbers);//length=12

FileOutputStream out = null;

try{

out = new FileOutputStream("file");

out.write(array);

}finally{

if(out!=null)

out.close();

}

سؤال: اگر این اعداد را در یک فایل متنی ذخیره می‌کردیم، چه تفاوتی داشت؟پاسخ: به جای 12 بایت، حداقل 30 بایت اشغال می‌شد







9.7) کلاس File

  1. کلاس java.io.File یک کلاس کمکی مفید برای کار با فایل‌ها و فولدرها است.

  2. از این کلاس برای خواندن از فایل و نوشتن در فایل استفاده نمی‌شود.

  3. شبیه Reader/Writer. یا InputStream/OutputStream نیست

  4. مثال:

File f = new File("1.txt");

long length = f.length();

boolean isdir = f.isDirectory();

long lastModified = f.lastModified();

  1. برخی از متدهای کلاس فایل:

    1. boolean canRead();

    2. boolean canWrite();

    3. boolean canExecute();

    4. long lastModified();

    5. boolean exists();

    6. boolean isFile() ;

    7. boolean isDirectory() ;

    8. String getName();

    9. String getAbsolutePath() ;

    10. String getParent();

    11. long length() ;//zero for folders

    12. String[] list() ;









9.8) کلاس RandomAccessFile

  1. این کلاس نه reader/writer است، و نه inputstream/outputstream

  2. با کمک این کلاس می‌توانید فایل را به‌صورت باینری یا متنی استفاده کنید(برای خواندن یا نوشتن)

  3. شیئی از این کلاس دارای یک عدد به عنوان اشاره‌گر فایل (file pointer) است. محلی از فایل که از آن می‌خوانیم یا در آن می‌نویسیم

  4. می‌توانید با استفاده از متد seek(long) این اشاره‌گر را جابجا کنید

  5. متدهای مختلفی برای خواندن یا نوشتن دارد

RandomAccessFile raf = new RandomAccessFile("1.txt", "rw");

//reads a single byte:

byte ch = raf.readByte();

//reads a 32-bit integer (binary read)

int i = raf.readInt();

//reads text

String line = raf.readLine();

//5 bytes from the beginning of the file

raf.seek(5);

//write text

raf.writeBytes("This will complete the Demo");

//wriet 8-bytes (binary)

raf.writeDouble(1.2);

raf.close();







9.9) کلاس Scanner



  1. کلاسی کمکی است که برای دریافت و پردازش متنی مناسب است

  2. کلاس Scanner در بسته java.io نیست (در java.util است)

  3. مثال:

Scanner s = new Scanner(System.in);

String line = s.nextLine();

int i = s.nextInt();



  1. اکنون می‌دانیم که System.in یک جریان ورودی (InputStream) است

  2. کلاس Scanner می‌تواند با انواع InputStream ها و Reader ها کار کند

s = new Scanner("1.txt");

s = new Scanner(new File("1.txt"));

s = new Scanner(new FileInputStream("1.txt"));

s = new Scanner(new FileReader("1.txt"));



9.10) کلاس Formatter

  1. این کلاس نیز در بسته java.util است

  2. برای تولید خروجی متنی استفاده می‌شود



Formatter f = new Formatter(new FileWriter("1.txt"));

f = new Formatter(new FileOutputStream("1.txt"));

f = new Formatter(new File("1.txt"));

f = new Formatter("1.txt");

f = new Formatter(System.out);



  1. دارای متد format : مشابه printf در C خروجی قالب‌بندی‌شده تولید می‌کند

  2. مثال:

f.format("age=%d,name=%s,grade=%.2f", 20, "Ali", 18.453);

9.11) کلاس‌های Closeable

  1. بسياری از کلاس‌های مربوط به خواندن/نوشتن از فایل‌ها و جریان‌ها Closeable هستند

  2. واسط Closeable را پیاده‌سازی می‌کنند که دارای متد close است

  3. InputStream, OutputStream, Reader, Writer, Scanner, Formatter, Socket, ServerSocket, …

  4. در انتهای کار با این اشیاء، باید آن‌ها را close کنیم

  5. از نسخه 7 (JDK 1.7)، واسط Closeable زیرواسط AutoCloseable شده‌است

  6. کلاس‌های AutoCloseable امکان try-with-resources دارند

  7. با این امکان، منابع به صورت خودکار در انتهای بلوک try بسته می‌شوند









9.12) برنامه نویسی شبکه



  1. روشی که دو برنامه را برای تبادل اطلاعات به هم متصل می‌کند

  2. این دو برنامه می‌توانند در دو کامپیوتر مختلف باشند که با شبکه به هم متصلند

  3. برنامه‌نویسی سوکت (socket programming): رایج‌ترین روش برنامه‌نویسی شبکه است

  4. برنامه کلاینت (client socket) به برنامه سرور (server socket) متصل می‌شود

  5. برای اتصال، باید آدرس (نام یا IP) و شماره پورت (port) برنامه سرور مشخص شود

  6. کاربردها: و بازی تحت شبکه و چَت و انتقال فایل و ...





9.12.1)کلاس Socket

  1. کلاس‌های جاوا برای برنامه‌نویسی شبکه در بسته java.net قرار دارند

  2. کلاس java.net.Socket ارتباط بین دو برنامه را ممکن می‌کند

  3. یک جریان داده (stream) بین دو برنامه ایجاد می‌کند

  4. مثال

: socket = new Socket("google.com", 80);

  1. یک برنامه برای ارسال داده به برنامه دیگر در «خروجی سوکت» می‌نویسد

OutputStream out = socket.getOutputStream();

  1. برای دریافت داده از برنامه دیگر از «ورودی سوکت» می‌خواند

InputStream inp = socket.getInputStream();

  1. مثال: نوشتن در سوکت

Socket socket = new Socket("192.168.10.21", 8888);

OutputStream outputStream = socket.getOutputStream();

Formatter formatter = new Formatter(outputStream);

formatter.format("Salam!\n");

formatter.flush();

formatter.format("Chetori?\n");

formatter.flush();

formatter.format("exit");

formatter.flush();

socket.close();

System.out.println("finished");



  1. خواندن از سوکت

InputStream inputStream = socket.getInputStream();

Scanner scanner = new Scanner(inputStream);



while(true){

String next = scanner.next();

if(next.contains("exit"))

break;

System.out.println("Server : " + next);

System.out.flush();

}

socket.close();







9.12.2)کلاس ServerSocket

  1. برای اتصال به برنامه دیگر، آن برشنامه باید «منتظر» دریافت تماس باشد.به این کار، «گوش به زنگ بودن» (listen) می‌گوییم

  2. کلاس ServerSocket انتظار برای دریافت ارتباط را فراهم می‌کند

  3. برای سرور لازم است: مثلاً سرورهای گوگل و یاهو منتظر تماس از طرف کاربران هستند

  4. هر شیء از نوع ServerSocket روی یک پورت کار می‌کند

  5. با فراخوانی متد accept گوش‌به‌زنگ می‌شود

  6. هر گاه یک برنامه به آن وصل شود، متد accept پایان می‌یابد

  7. با پایان متد accept یک شیء از نوع Socket برای برقراری ارتباط ایجاد می‌شود

ServerSocket serverSocket = new ServerSocket(8888);

Socket socket = serverSocket.accept();

  1. مثال برنامه سِرور

try(ServerSocket server = new ServerSocket(8765);

Socket socket = server.accept();

Scanner in = new Scanner(socket.getInputStream());

Formatter out = new Formatter(socket.getOutputStream());){

String next;

do{

next = in.next();

String translate = translate(next);

out.format(translate+"\n");

out.flush();

}while(!next.equals("exit"));

}

  1. مثال: برنامه کلاینت

try(Socket socket = new Socket("localhost", 8765);

Scanner socketIn = new Scanner(socket.getInputStream());

Formatter socketOut =

new Formatter(socket.getOutputStream());

Scanner systemIn = new Scanner(System.in);){

String next;

do{

next = systemIn.next();

socketOut.format(next+"\n");

socketOut.flush();

String received = socketIn.next();

System.out.println("received: "+received);

}while(!next.equals("exit"));

}



9.12.3)نکات

  1. برنامه‌های سرور و کلاینت می‌توانند بر روی یک کامپیوتر اجرا شوند(بدون اتصال به یک شبکه)

  2. آدرس کامپیوتر جاری: localhost یا 127.0.0.1

  3. تبادل اطلاعات با کمک سوکت می‌تواند به صورت باینری باشد

byte[] bytes = new byte[]{1,5,127,7};

socket.getOutputStream().write(bytes);

  1. معمولاً برنامه سرور، یک برنامه چندنخی (Multi-Thread) است. تا بتواند همزمان به چند کاربر خدمت‌رسانی کند



9.13) مفهوم Serialization

  1. در جاوا می‌توانیم یک شیء را به یک جریان داده ارسال کنیم.مثلاً در یک فایل ذخیره کنیم، یا از طریق شبکه به کامپیوتر دیگری بفرستیم.به این فرایند، Serialization می‌گویند.

  2. سپس می‌توانیم از یک جریان ورودی، شیء را بازیابی کنیم. مثلاً با کمک فایلی که شیء را ذخیره کرده، آن شیء را دوباره ایجاد کنیم. به این فرایند، Deserialization می‌گویند (برعکس Serialization)

  3. این امکان، برای هر شیئی که واسط Serializable را پیاده‌سازی کند، ممکن است

  4. واسط java.io.Serializable هیچ متدی ندارد:

public interface Serializable {}





9.13.1)اشیاء Serializable

  1. بسياری از کلاس‌ها در جاوا Serializable هستند. مثل String ، Integer ، ArrayList و … که اشیاء این کلاس‌ها قابل تبدیل به «جریانی از بایت‌ها» هستند و قابل بازسازی از «جریانی از بایت‌ها» هستند.

  2. عملیات Serialization یعنی تبدیل شیء به یک جریان باینری. در این عملیات، همه ویژگی‌های درون شیء (یعنی فیلدها) ذخیره می‌شوند. البته به جز فیلدهایی که با کلیدواژهtransient مشخص شده باشند

  3. معنای برچسب transient برای فیلدهای کلاس این است که هنگام عملیات Serialization فیلدهای transient ذخیره نمی‌شوند

class User implements Serializable {

private String username;

private transient String password;

...

}



class Student implements Serializable {

private String name;

private double[] grades;

private transient double average = 17.27;

}



FileOutputStream f1 = new FileOutputStream("c:/1.txt");

ObjectOutputStream out = new ObjectOutputStream(f1);

Student st = new Student("Ali", new double[]{17.0, 18.0});

System.out.println(st.name);

System.out.println(st.average);

out.writeObject(st);

out.close();



FileInputStream f2 = new FileInputStream("c:/1.txt");

ObjectInputStream in = new ObjectInputStream(f2);

Student s2 = (Student) in.readObject();

System.out.println(s2.name);

System.out.println(s2.average);

in.close();



class Student implements Serializable {

String name; double[] grades;

transient double average;

...

}







9.14) برخی کلاس‌های مهم java.io

  1. DataInputStream و DataOutputStream که برای نوشتن و خواندن باینری می‌باشند و دارای امکاناتی برای خواندن مقادیر اولیه:

readBoolean, readChar, readDouble, readInt, readFloat, readLong,…

  1. BufferedReader و BufferedWriter و BufferedInputStream و BufferedOutputStream:

    1. ورودی و خروجی بافر شده.

    2. بافر (buffer): تکنیکی برای افزایش کارایی

    3. هر عملیات «نوشتن»، لزوماً بلافاصله اجرا نمی‌شود (شاید بافر شود، متد flush)

    4. هر «خواندن» شاید به خوانده شدن گسترده منجر شود (ایجاد بافر برای خواندن‌های بعدی)

    5. مثلاً خواندن با کمک BufferedReader سریعتر از Scanner است

  2. ByteArrayInputStream و ByteArrayOutputStream: برای خواندن و نوشتن باینری در یک آرایه از بایت‌ها

  3. StringReader و StringWriter: برای خواندن و نوشتن متنی در یک رشته

  4. PrintStream:

    1. تولید خروجی متنی در یک OutputStream

    2. دارای متدهای متنوع print و println (مثلاً System.out)



9.15) الگوی طراحی Decorator در کلاس‌های java.io

  1. اشیائی که برای خواندن و نوشتن در جریان‌های داده استفاده می‌شوند

  2. می‌توانند در ترکیب و تعامل با هم استفاده شوند

  3. سازنده (constructor) بسياری از کلاس‌های io ، امکان دریافت منبعی دیگر را دارند. مثال:

FileOutputStream file = new FileOutputStream("c:/f.txt");

BufferedOutputStream buffer = new BufferedOutputStream(file);

PrintStream print = new PrintStream(buffer);



print.println("salam");

  1. طراحی کلاس‌های io در جاوا از الگوی Decorator استفاده می‌کند

  2. یک الگوی طراحی (Design Pattern) است

ByteArrayOutputStream baos = new ByteArrayOutputStream();

DataOutputStream dos = new DataOutputStream(baos);

byte[] bytes;



dos.writeInt(2147483647);

bytes = baos.toByteArray();

System.out.println(bytes.length); //4



baos.reset();



dos.writeDouble(1);

bytes = baos.toByteArray();

System.out.println(bytes.length); //8





9.16) امکانات NIO و NIO.2

  1. بسته java.io از قدیم در جاوا بوده است

  2. از نسخه 1.4 بسته java.nio شامل امکانات جدید (new io) اضافه شد (2002)

  3. از نسخه 1.7 بسته java.nio.file اضافه شد (به آن NIO.2 گفته می‌شود)

  4. کلاس‌ها و واسط‌های جدیدی در java.nio.file ارائه شدند. مانند: Path, Paths, Files

  5. این امکانات تلاش می‌کنند محدودیت‌های کلاس java.io.File را برطرف کنند

  6. قابلیت‌هایی مورد نیاز است که در کلاس File وجود ندارد (مانند کپی فایل‌ها)



9.17) کلاس Paths و واسط Path

  1. هر دو در بسته‌‎ی java.nio.file هستند (NIO.2)

  2. کلاس Paths یک کلاس کمکی است که فقط شامل متد get است

  3. متد get یک آدرس می‌گیرد و شیئی از نوع Path برمی‌گرداند

Path path = Paths.get("c:/f.txt");

  1. هر شیء از نوع واسط Path ، اطلاعاتی درباره فایل یا فولدر موردنظر دارد

  2. برخی از امکاناتی که در کلاس java.io.File دیدیم، در واسط Path وجود دارد

  3. در نسخه‌های جدید جاوا بهتر است حتی‌الامکان از Path به جای File استفاده کنیم

  4. امکان تبدیل File به Path و برعکس هم وجود دارد

  5. متد toFile در واسط Path و متد toPath در کلاس File وجود دارد

Path parent = path.getParent();

File f = path.toFile();





9.18) کلاس java.nio.file.Files

  1. کلاسی کمکی دارای متدهای متنوع استاتیک متنوع و مفید برای دریافت ويژگی‌های فایل، کپی فایل، جابجایی، حذف و ...

  2. برخی از امکانات کلاس قدیمی java.io.File را دارد

  3. بهتر است حتی‌الامکان از امکانات Files به جای File استفاده کنیم

  4. امکانات این کلاس با کمک Path پیاده شده‌اند

  5. امکانات و متدهای جدیدی نیز دارد.

  6. برای فایل‌های پیوندی نمادین (symbolic link) کاربرد دارد. ویژگی‌های فایل‌ها کاربرد دارد و …

  7. مثال:

Path src = Paths.get("/home/ali/src.txt");

if(!Files.exists(src)) return;

Files.createDirectory(Paths.get("/folder/newfolder"));

Files.createSymbolicLink(Paths.get("/home/l.txt"), src);

byte[] bytes = Files.readAllBytes(src);

List<String> lines = Files.readAllLines(src);

boolean writable = Files.isWritable(src);

long size = Files.size(src);

Path copy = Paths.get("c:/folder/copy.txt");

Files.write(copy, bytes);

Files.write(copy, lines, StandardOpenOption.APPEND);

Files.copy(src, Paths.get("c:/folder/dest.txt"));

Files.delete(src);









9.19) امکان try-with-resources

قبل از جاوا 7

FileReader fr = new FileReader("1.txt");

try {

int read = fr.read();

...

}finally {

if (fr != null) fr.close();

}

بعد از جاوا 7

try (FileReader fr = new FileReader("1.txt")){

int read = fr.read();

...

}







9.20) خطاهای مربوط به کار بافایل

9.20.1)خطای IOException



  1. هنگام کار با فایل‌ها و جریان‌ها، ممکن است خطای IOException پرتاب شود مثلاً: خواندن از فایلی که وجود ندارد (FileNotFoundException) -نقض مجوز دسترسی به فایل.مثال:

try {

FileWriter writer= new FileWriter("f.txt");

writer.write("a line. \n");

writer.close();

} catch (IOException e) {

e.printStackTrace();

}







9.21) مرور و موارد تکیمیلی

  1. برای تشخیص اندازه یک فایل از FileReader استفاده کنیم یا File ؟پاسخ: File

  2. کدام کلاس هم برای خواندن و هم برای نوشتن در فایل قابل استفاده است؟[File, RandomAccessFile, Formatter,]-[InputStream] ؟ پاسخ: RandomAccessFile

  3. اگر محتوای فایلی که با کمک FileWriter ایجاد شده را با کمک یک FileInputStream بخوانیم، با خطا (exception) مواجه می‌شویم؟ پاسخ: خیر - هر محتوای متنی را به صورت یک جریان باینری هم می‌توانیم بخوانیم، و برعکس -اما معمولاً این کار بی‌فایده است