دانستنی‌ها

ویژگی‌های مخفی زبان جاوا

حقه‌ها یا ویژگی‌های مخفی در هر محصول نرم‌افزاری بسیار جذاب هستند. اما آیا چنین حقه‌هایی در زبان برنامه‌نویسی جاوا نیز وجود دارد؟

توسعه‌دهندگان زبان جاوا در زمان کار خود با این زبان برنامه‌نویسی احتمالا با حقه‌هایی روبرو شده‌اند که برایشان جذاب بوده است. در ادامه چند مورد آن را اشاره می‌کنیم:

۱. مقداردهی اولیه با زوج آکولادها: به عنوان مثال مقدار دهی به شکل زیر را داریم:

Set<String> validCodes = new HashSet<String>();
 validCodes.add("XZ13s");
 validCodes.add("AB21/X");
 validCodes.add("YYLEX");
 validCodes.add("AR2D");
 removeProductsWithCodeIn(validCodes);

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

private static final Set<String> VALID_CODES = new HashSet<String>() {{
	add("XZ13s");
	add("AB21/X");
	add("YYLEX");
	add("AR2D");
 }};

یا

removeProductsWithCodeIn(new HashSet<String>() {{
	add("XZ13s");
	add("AB21/X");
	add("YYLEX");
	add("AR5E");
 }});

۲. ThreadLocals: معمولا خیلی به عنوان یک راه برای ذخیره حالت هر ریسه شناخته نمی‌شوند.

طبق توضیح جواب‌یاب، Thread Local در حقیقت شبیه یک scope است (مانند request scope یا session scope) و می توان به آن thread scope گفت. اشیائی که از کلاس ThreadLocal ساخته می شوند مانند یک map عمل می کنند و قابلیت ذخیره سازی هر شئی را برای هر thread دارند، کلاس ThreadLocal را می توان شبیه یک map تصور کرد که کلید آن یک thread و مقادیر آن اشیاء می باشد.

۳. Join Union  در نوع پارامترها

public class Baz<T extends Foo & Bar> {}

برای مثال اگر بخواهیم یک پارامتر هم Comparable باشد و هم یک Collection، به شکل زیر خواهیم داشت:

public static <A, B extends Collection<A> & Comparable<B>>
boolean foo(B b1, B b2, A a) {
   return (b1.compareTo(b2) == 0) || b1.contains(a) || b2.contains(a);
}

۴. مقدار دهی اولیه نمونه‌ها

به کد زیر دقت کنید:

public class App {
    public App(String name) { System.out.println(name + "'s constructor called"); }

    static { System.out.println("static initializer called"); }

    { System.out.println("instance initializer called"); }

    static { System.out.println("static initializer2 called"); }

    { System.out.println("instance initializer2 called"); }

    public static void main( String[] args ) {
        new App("one");
        new App("two");
  }
}

بعد از اجرای تابع main خروجی به شکل زیر است:

static initializer called
static initializer2 called
instance initializer called
instance initializer2 called
one's constructor called
instance initializer called
instance initializer2 called
two's constructor called

این کار در صورتی که بخواهیم چند constructor داشته باشیم و یک کد مشترک نیاز داشته باشند.

به علاوه یک syntatic sugar برای مقدار دهی اولیه کلاس‌هایتان فراهم می‌کند.

List<Integer> numbers = new ArrayList<Integer>(){{ add(1); add(2); }};

Map<String,String> codes = new HashMap<String,String>(){{ 
  put("1","one"); 
  put("2","two");
}};

۵. از JDK 1.6_07 به بعد یک برنامه به اسم VisualVM (bin/jvisualvm.exe) داریم که یک GUI زیبا روی بسیاری از ابزارهاست و خیلی کامل‌تر از JConsole به نظر می‌رسد.

۶. برای بسیاری از افراد بلوک‌های برچسب‌دار در جاوا شگفت آور است. این یک مثال از آن است:

getmeout:{
    for (int i = 0; i < N; ++i) {
        for (int j = i; j < N; ++j) {
            for (int k = j; k < N; ++k) {
                //do something here
                break getmeout;
            }
        }
    }
}

۷. برای استفاده از instanceof بررسی null بودن یا نبودن ضرورتی ندارد به جای استفاده از :

if( null != aObject && aObject instanceof String )
{
    ...
}

تنها کد زیر را استفاده کنید:

if( aObject instanceof String )
{
    ...
}

۸. امکان استفاده از توابع و constructorها در enum برای بسیاری از افراد باعث شگفتی است. برای مثال:

enum Cats {
  FELIX(2), SHEEBA(3), RUFUS(7);

  private int mAge;
  Cats(int age) {
    mAge = age;
  }
  public int getAge() {
    return mAge;
   }
}

مستندات بیشتر در اینجا قابل مشاهده است.

۹. تایپ پارامترها برای توابع به صورت صریح به شکل زیر قابل مشخص کردن است:

Collections.<String, Integer>emptyMap()

۱۰.از جاوا ۱.۵ به بعد، جاوا سینتکس خیلی تمیزی برای نوشتن توابعی از متغیرها با تعداد متفاوت اضافه کرده است. بنابراین به جای پاس دادن آرایه می توان کار زیر را انجام داد:

public void foo(String... bars) {
   for (String bar: bars)
      System.out.println(bar);
}

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

foo("first","second","third")

شما چه ویژگی‌های دیگری می‌شناسید که موجب شگفتی‌تان شده اند؟ از ویژگی‌های گفته شده از کدامیک بی‌اطلاع بودید؟

منبع:

http://stackoverflow.com/

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا