فؤاد المالكي @eng.fouad

Java SE/EE/FX, Android Developer

نقاط السمعة 216
تاريخ التسجيل 25/08/2013
آخر تواجد سنة

تفضل.

أنصح بالمكتبة JSoup للتعامل مع طلبات الـ HTTP والتعامل مع مستندات HTML:

وإذا أردت دعم للجافاسكربت ومميزات أكثر، أنصحك بالمكتبة HTMLUnit:

الخطأ الذي وقعت فيه هو خطأ شائع عند مبرمجي جافا المبتدئين. لا تقارن بين اثنين من نوع String بالعلامة == (المقارنة هنا تعني ما إذا كان الاثنان يشيران لنفس الكائن في الذاكرة أم لا، ولا يتم مقارنة قيمتهما)، ولكن قارن بينهما بالدالة ()equals أو ()equalsIgnoreCase إذا أردت تجاهل حالة الأحرف كانت كبيرةً أم صغيرةً. لذلك أول شرط من المفترض أن يكون هكذا:

if (!Job_spec.equalsIgnoreCase("DEVLOPER") && !Job_spec.equalsIgnoreCase("DESIGNER") && !Job_spec.equalsIgnoreCase("SELLER"))

أيضاً، ما الفائدة من هذا الشرط؟ يبدو لي أنه خطأ!

if (age_Designer < Job_age || age_Dev < Job_age || age_Seller < Job_age)

جميل جداً. تم التسجيل في الموقع، وتم نشر وتثبيت رابط الموقع في مجموعة عبدالله عيد على الفيسبوك:

الجافاسكربت عموماً لا يقوم بتغيير ملف صفحة الويب على السيرفر، وإنما النسخة الحالية المعروضة في المتصفح. عند تحديث الصفحة، يتم جلب النسخة الأصلية من السيرفر (أو من نظام الملفات إذا كانت الصفحة محلية).

بالطبع تحتاج إلى JDK، ولكن ليس بالضرورة إلى IDE.

يقصد الأداة javac والتي تحول الـ source code (بصيغة java.) إلى binary code (بصيغة class.) وهي التي يفهمها الـ JVM.

تجد الأداة javac في الويندوز مثلاً على هذا المسار غالباً:

C:\Program Files\Java\jdk1.8.0_60\bin\javac.exe
10

this هي كلمة محجوزة (keyword) تشير للعيّنة الحالية (current instance) من هذا الصنف (class) في عالم الكائنات (Object Oriented).

مقدمة عن عالم الكائنات:

من المعروف أن الـ class ما هو إلى وصف لشيء. وصف للصفات (fields) والأفعال (methods). فمثلاً الصنف Car يحتوي على عدة صفات مثل model - color - topSpeed، ويحتوي على عدة أفعال مثل startEngine - move.

من هذا الصنف يمكن إنشاء عيّنات (instances) باستخدام الكلمة المحجوزة new مع استدعاء دالة البناء (constructor). فمثلاً ننشيء عينةّ يكون نوعها Car وتكون صفاتها مثلاً:

model = 2016

color = white

topSpeed = 240

وعيّنة أخرى من نفس النوع تكون صفاتها مثلاً:

model = 1995

color = black

topSpeed = 200

وبالرغم من أنهما يشتركان في نفس الأفعال، لكن هذه الأفعال تختلف في طريقة أدائها بسبب اختلاف الصفات.

استخدام this:

عندما نستخدم الكلمة this داخل الكود المصدري (source code) للصنف Car، فإنها تشير للعيّنة الحالية من هذا الصنف. بمعنى آخر، لاحظ الكود الآتي:

public int getTopSpeed()
{
    return this.topSpeed;
}

عند استدعاء هذه الدالة على العيّنة الأولى سيرجع لنا 240:

Car car1 = new Car(2016, "white", 240);
int topSpeed = car1.getTopSpeed();

بينما سيرجع لنا 200 لو تم استدعاؤها على العيّنة الثانية.

لاحظ بأن استخدام this غير ضروري هنا، بينما هو ضروري في المثال التالي:

public void setTopSpeed(int topSpeed)
{
    this.topSpeed = topSpeed;
}

لأنه إذا كان المتغير المحلي (local variable) بنفس اسم أحد الصفات، فإنه "سيطغى" عليه (variable shadowing). والحل هو إضافة this قبل اسم المتغير ليشير للصفة وليس للمتغير المحلي.

طبعاً هناك استخدامات متقدمة، مثل الوصول للمتغيرات والدوال لصنف خارجي (Enclosing Class) من داخل صنف داخلي (Inner Nested Class).

بالنسبة للكود فأنت عندما تمرر متغير بالقيمة فأنت تصل إلى قيمته وتتعامل مع نسخة من الكائن الأصل وبالتالي فإن أي تعديل على خصائصه لن يؤثر على الكائن الأصل

أما التمرير بالمرجع فأنت تمرر مرجع الكائن الأصل وبالتالي أي تعامل مع خصائصه فأنت تعدل على الأصل

كلام غير دقيق. يمكن تغيير خصائص الكائن من خلال "التمرير بالقيمة". كما أن التعامل يكون مع الكائن الأصل ذاته وليس نسخة منه.

"التمرير بالمرجع" يعني أنه يمكن إسناد قيمة جديدة للمرجع الذي تم تمريره داخل الدالة.

كتبت مقالة عن تجربتي مع امتحان OCA أول مستوى للـ JAVA SE:

حاولت الدخول بـ Eng.Fouad كاسم مستخدم، ولم يعمل. غيرت كلمة المرور، وما زالت المشكلة حاضرة. استخدمت الإيميل كاسم المستخدم ونجح الأمر.

استخدام DocumentListener هو الحل الأمثل هنا.

إذا كنت تقصد في الـ Client-Side، استخدم Java Preferences API:

انظر لها من طرف برنامج الجافا:

Input: المدخل إلى البرنامج (قراءة).

Output: المخرج من البرنامج (كتابة).

والمصدر قد يكون قراءة/كتابة من/إلى ملف، أول قراءة ما يكتبه المستخدم على الـ console أو كتابة نص ما ليقرأه المستخدم على الـ cosole. قد يكون أيضاً قراءة بيانات من الشبكة/الإنترنت (download)، وقد يكون كتابة بيانات إلى الشبكة/الإنترنت (Upload).

مكتبة java.io تنقسم إلى قسمين:

1- Byte Streams: وتعتمد على byte كوحدة، وأساسها الكلاسين InputStream و OutputStream.

2- Character Streams: وتعتمد على char كوحدة، وأساسها الكلاسين Reader و Writer.

طبعاً المكتبة java.io تعتمد على الـ Decorator Design Pattern، أي أن كلاس يضيف ميزة أخرى للأول. فمثلاً:

File file = new File("file.exe");
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);

لاحظ أن الـ FileInputStream يقوم بإنشاء InputStream من الـ File، والكلاس BufferedInputStream يضيف خاصية الـ buffering إلى الـ InputStream الأصلي. الكلاس DataInputStream يضيف ميزة قراءة primitive data types قد تم كتابتها مسبقاً بالكلاس DataOutputStream.

الأمر ذاته مع عالم الـ Reader/Writer، لكن عادةً يتم استخدام الكلاسين InputStreamReader و OutputStreamWriter للتحويل من Byte Stream إلى Character Stream:

URL arabia = new URL("

https://arabia.io "); URLConnection uc = arabia.openConnection(); BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) System.out.println(inputLine); in.close();

وللمعلومية، System.out و System.err ما هي إلا PrintStream وهي نوع من أنواع الـ OutputStream. يوجد مثيل لهذا الكلاس في عالم الـ Character Streams ألا وهو PrintWriter.

أيضاً System.in ما هو إلا InputStream بدون أي إضافات.

ملاحظة مهمة للجميع: الضغط على زر Commit غير كافي، بل يجب أيضاً تفعيل الحساب عن طريق الإيميل.

هذا يفسر عدد الزيارات أعلى من 3729، وعدد الذين ضغطوا على زر Commit وفعلوا الحساب 105 فقط.

+1 جميل جداً. أتمنى أن تضع هذا الرد في المقترح نفسه، بالضغط على "create new discussion"، حتى يستفيد الجميع.

تم نشره في وسائل التواصل الاجتماعي، والتفاعل جيد حتى الآن.

توجد طريقة أسرع لإنجاح هذا المقترح، ألا وهي الدخول على قائمة الأعلى نقاط في stackoverflow من العرب:

ثم الدخول على الأوائل من القائمة (أول 50 مثلاً)، وكتابة رد في أقدم جواب لكل منهم (حتى لا يلاحظ أحد ;))، بحيث تضع رابط المقترح وتطلب منه المشاركة.

من سيقوم بهذا العمل؟ :)

13

توجد بعض الطرق لحماية السورس الكود (إلى حدٍ ما) من الهندسة العكسية (عن طريق الـ decompilation):

1. الـ obfuscation: وهي طريقة تقوم بتغيير أسماء الكلاسات والدوال والمتغيرات، لكي يصعب على "الهاكر" فهم السورس كود. ومن أشهر الـ obfuscator هو ProGuard.

2. التحويل من byte-code إلى native-code: أي تقوم مثلاً بتحويل برنامج الجافا إلى exe، وبهذه الطريقة لن يمكن استرجاع كود الجافا الأصلي. لكن يعيب هذه الطريقة هو أنك لن تتمكن من تشغيل البرنامج على الأنظمة الأخرى، بعكس ما يميز برامج الجافا. ومن أشهر الأدوات لعمل ذلك هو Excelsior JET.

3. تشفير ملف الكلاس، وأثناء الـ runtime، يقوم برنامج الجافا بفك التشفير وإضافته إلى الـ ClassLoader. على أية حال، يستطيع "الهاكر" عمل هندسة عكسية للكود الذي يقوم بفك تشفير ملف الكلاس.

4. جعل الكود يعمل على server، وجعل الـ client يتخاطب معه عبر الإنترنت (عبر البروتوكول HTTP مثلاً). وهذه تعتبر أفضل طريقة لحماية الكود من الهاكرز.

فضيحة كبيرة للجافا؟ جميع اللغات يوجد فيها decompilation. على أية حال، توجد أدوات وبرامج تقوم بتحويل برامج الجافا من byte-code إلى native-code، وبالتالي لن تستطيع إعادة كود الجافا الأصلي، ولكن يمكن الإعادة لكود السي/سي بلص بلص، وأيضاً لن تستطيع تشغيل البرنامج على الأنظمة الأخرى.

جميل جداً، وأنا من أول الداعمين لهذا الإقتراح، بل أنني قمت بفتح مثل هذا الاقتراح قبل سنتين ولكن لم يتعدى المرحلة الأولى:

بما أنك قادر على تشغيل البرنامج، وبما أن الخطأ هو NoClassDefFoundError للكلاس jade.wrapper.ControllerException، يمكن استنتاج أن المشكلة هي كالتالي:

  • عندما قمت بعمل compile للكلاس MainContainer، كان الكلاس jade.wrapper.ControllerException موجود في الـ classpath. بينما أثناء عمل run للكلاس MainContainer، الكلاس jade.wrapper.ControllerException لم يكن موجوداً في الـ classpath.

يوجد نوعين من JavaDB:

Server DB

Embedded DB

استخدم النوع الثاني.

الثوابت تجدها دائماً static و final، وذلك يعني بأن قيمتها ثابتة، وأنها مشتركة بين جميع العينات من نفس الكلاس بدلاً من إنشاء نسخة جديدة من المتغير مع إنشاء كل كائن جديد.

17

المتغير المعرف بـ final، لا يمكن إعطاءه قيمة جديدة من بعد أن ما تم إعطائه قيمة أولية. بمعنى آخر، لو لدينا متغير نصي من نوع local variable (أي داخل دالة) وقمنا بتعريفه كـ final:

final String a;

فإنه لا يقبل إسناد قيمة له إلا مرة واحدة:

final String a;
a = "test";
a = "test2"; // ERROR

أو

final String a = "test";
a = "test2"; // ERROR

يمكن أيضاً تعريف الـ parameter كـ final، ويعني بأن قيمته ستكون ثابتة داخل الدالة:

public void foo(final int param(
{
    param = 6; // ERROR
    param++; // ERROR
}

يمكن أيضاً تعريف instance variable كـ final، ويجب إسناد قيمة أولية له إما بشكلٍ مباشر أو من خلال الـ constructor أو بداخل instance initializer:

public class Test
{
    private final ClassA a = new ClassA();
    private final ClassB b;
    private final ClassC c;

    public Test()
    {
        b = new ClassB();
    }

    {
        c = new ClassC();
    }

}

يمكن أيضاً تعريف static variable كـ final، ويجب إسناد قيمة أولية له إما بشكلٍ مباشر أو من خلال الـ static initializer:

public class Test
{
    private static final ClassA a = new ClassA();
    private static final ClassB b;

    static
    {
        b = new ClassB();
    }

}

يرجى ملاحظة أنه في حالة الكائنات ما زال بإمكانك التعديل على نفس الكائن، ولكن لا يمكن تغير الكائن الذي يشير إليه المتغير:

final ClassA a = new ClassA();
a.setX(123);
a = new ClassA(); // ERROR

يستخدم final أيضاً على مستوى الكلاس ويعني أن الكلاس لا يمكن الوراثة منه. يستخدم final أيضاً على مستوى الدالة ويعني بأن الدالة لا يمكن عمل Override لها.


بالنسبة لـ static، فكما ذكر الأخ WGH، تعني بأن المتغير مشترك بين جميع العينات بعكس الـ instance variable والذي يعني أن كل كائن له نسخة خاصة من ذلك المتغير.

باختصار: مجموعة من الدوال تُستخدَم للاستفادة من مكتبة برمجية معينة أو خدمة معينة.

مثلاً، Twitter API هي مجموعة من الدوال على هيئة HTTP requests تستخدم للاستفادة من خدمات Twitter من تغريد وإعادة تغريد وغيرها من الخدمات. مثال آخر، المكتبة JMF في لغة الجافا، هي مكتبة برمجية تستخدم دوالها (its APIs) للتعامل مع الـ media من فيديو وأصوات.