IBM Korea Skip to main content
       IBM Ȩ    |  Á¦Ç° & ¼­ºñ½º  |  °í°´Áö¿ø & ´Ù¿î·Îµå  |  È¸¿ø°¡ÀÔ  

JML ½ÃÀÛÇϱâ
JML ÁÖ¼®À¸·Î ÀÚ¹Ù ÇÁ·Î±×·¥ Çâ»ó½ÃÅ°±â

Level: Intermediate

Joe Verzulli
Consultant
2003³â 3¿ù 18ÀÏ

Java Modeling Language (JML)´Â ¸Þ¼Òµå¿Í Ŭ·¡½º¿¡ ´ëÇÑ »õ·Î¿î »ç°í¹æ½ÄÀ» °¡Á®´ÙÁÖ´Â ¼¼¹ÐÇÑ µðÀÚÀÎÀÇ ¾ð¾îÀÌ´Ù. ÀÚ¹Ù ÇÁ·Î±×·¡¹Ö ÄÁ¼³ÅÏÆ®ÀÎ Joe Verzulli´Â JML°ú ÀÌ°ÍÀÇ ¼±¾ðÀû ±¸Á¶Ã¼µéÀ» ¼Ò°³ÇÑ´Ù.

Java Modeling Language (JML)Àº ¹æ¹ýÀ» ¸»ÇÏÁö ¾ÊÀº ä ¸Þ¼Òµå°¡ ¹«¾ùÀ» ¼öÇà ÇÒ °ÍÀΰ¡¸¦ ÁöÁ¤Çϵµ·Ï ÇÏ´Â ÀÚ¹Ù Äڵ忡 ÁÖ¼®À» Ãß°¡ÇÑ´Ù. JMLÀ» ÀÌ¿ëÇؼ­, ¿ì¸®´Â ±¸Çö°ú °ü°è¾øÀÌ ¸Þ¼ÒµåÀÇ ÀǵµµÈ ±â´ÉÀ» ¼³¸íÇÒ ¼ö ÀÖ´Ù. ÀÌ ¹æ½ÄÀ¸·Î JMLÀº ÀýÂ÷Àû »ç°í¸¦ ¸Þ¼Òµå µðÀÚÀÎ ´Ü°è·Î ¹Ì·ç´Â °´Ã¼ ÁöÇâ ¿ø¸®´Â È®ÀåÇÑ´Ù.

JMLÀº ÀÛµ¿À» ¼±¾ð½ÄÀ¸·Î ¼³¸íÇϱâ À§ÇØ ¼ö ¸¹Àº ±¸Á¶Ã¼µéÀ» µµÀÔÇß´Ù. ¿©±â¿¡´Â ¸ðµ¨ Çʵå, ÇÑÁ¤»ç(quantifier), ¼±¾ð¿ë ½Ã°¢ ¹üÀ§, ÀüÁ¦Á¶°Ç, ÈÄÁ¶°Ç, ºÒº¯ °ª, contract »ó¼Ó, Á¤»ó ÀÛµ¿°ú ¿¹¿ÜÀû ÀÛµ¿¿ë ½ºÆÑ µîÀÌ Æ÷ÇԵǾî ÀÖ´Ù. ÀÌ·¯ÇÑ ±¸Á¶Ã¼µé·Î ÀÎÇØ JMLÀº ¸Å¿ì °­·ÂÇÏ°Ô µÇÁö¸¸ ÀÌµé ¸ðµÎ¸¦ ÀÌÇØÇÏ·Á°í Çϰųª »ç¿ëÇÒ ÇÊ¿ä´Â ¾ø´Ù.

JML °³°ý
Ŭ·¡½º¿Í ¸Þ¼ÒµåÀÇ ¸ñÇ¥ ÀÛµ¿À» ¼³¸íÇϱâ À§ÇØ JMLÀ» »ç¿ëÇϸé Àüü °³¹ß ÇÁ·Î¼¼½º°¡ ÈξÀ Çâ»óµÈ´Ù. ÀÚ¹Ù Äڵ忡 ¸ðµ¨¸µ Ç¥±â¸¦ Ãß°¡ÇÒ ¶§ÀÇ ÀÌÁ¡Àº ´ÙÀ½°ú °°´Ù:

  • Äڵ尡 ¼öÇàÇÏ´Â °ÍÀ» ´õ¿í ÀÚ¼¼ÇÏ°Ô ¼³¸í
  • È¿À²ÀûÀÎ ¹ß°ß°ú ¹ö±× Á¤Á¤
  • ¾ÖÇø®ÄÉÀ̼ÇÀÌ ÁøÈ­¿¡ µû¸¥ ¹ö±× °¨¼Ò
  • À߸ø »ç¿ëµÈ Ŭ·¡½ºÀÇ Á¶±â ¹ß°ß
  • ¾ÖÇø®ÄÉÀÌ¼Ç ÄÚµå¿Í ¾ðÁ¦¶óµµ ¿¬°áµÇ´Â Á¤È®ÇÑ ¹®¼­

JML ÁÖ¼®Àº ¾ðÁ¦³ª ÀÚ¹Ù ÄÄÆ÷³ÍÆ® ¾È¿¡ ÀÖ´Ù. µû¶ó¼­ Á¤»óÀûÀ¸·Î ÄÄÆÄÀϵǴ Äڵ忡 ¿µÇâÀ» ¹ÌÄ¡Áö ¾Ê´Â´Ù. ¿ÀÇ ¼Ò½º JML ÄÄÆÄÀÏ·¯ (Âü°íÀÚ·á)´Â Ŭ·¡½ºÀÇ ½ÇÁ¦ ÀÛµ¿°ú JML ½ºÆÑÀ» ºñ±³ÇÒ ¶§ »ç¿ëµÉ ¼ö ÀÖ´Ù. JML ÄÄÆÄÀÏ·¯·Î ÄÄÆÄÀÏµÈ ÄÚµå´Â, Äڵ尡 ½ºÆÑÀÌ Á¤ÇÑ °ÍÀ» ¼öÇàÇÏÁö ¾ÊÀ» ¶§, ·±Å¸Àӽà JML ¿¹¿Ü¸¦ ¸¸µç´Ù. ÀÌ´Â Äڵ忡¼­ ¹ö±×¸¦ ÀâÀ» »Ó¸¸ ¾Æ´Ï¶ó ¹®¼­°¡ ÄÚµå¿Í ¿¬µ¿µÈ »óÅ·ΠÀÖ°Ô µÈ´Ù.

´ÙÀ½ ¼½¼Ç¿¡¼­´Â Jakarta Commons Collection Component (JCCC)ÀÇPriorityQueue ÀÎÅÍÆäÀ̽º¿Í BinaryHeap Ŭ·¡½º¸¦ »ç¿ëÇÏ¿© JMLÀÇ Æ¯Â¡À» ¼³¸íÇÒ °ÍÀÌ´Ù. (Âü°íÀÚ·á).

ÇÊ¿äÁ¶°Ç°ú Ã¥ÀÓ
ÀÌ ±ÛÀÇ ¼Ò½º Äڵ忡´Â (Âü°íÀÚ·á) JCCCÀÇ PriorityQueue°¡ Æ÷ÇԵǾî ÀÖ´Ù. PriorityQueue ÀÎÅÍÆäÀ̽º¿¡´Â ÀÎÀÚÀÇ µ¥ÀÌÅÍ Å¸ÀÔ°ú ¸®ÅÏ °ªÀ» Á¤ÀÇÇÑ ¸Þ¼Òµå ¼­¸íÀÌ Æ÷ÇԵǾîÀÖÁö¸¸ ¸Þ¼ÒµåÀÇ ÀÛµ¿¿¡ ´ëÇؼ­´Â ¼³¸íÀÌ ¾ø´Ù. PriorityQueueÀÇ Àǹ̸¦ ÁöÁ¤ÇÏ¿© À̸¦ ±¸ÇöÇÏ´Â ¸ðµç Ŭ·¡½º°¡ ¿øÇÏ´Â ¹æ½Ä´ë·Î ÀÛµ¿µÇ±â¸¦ ¹Ù¶õ´Ù.

PriorityQueueÀÇ pop() ¸Þ¼Òµå¿¡ ´ëÇØ »ý°¢Çغ¸ÀÚ. ¿ì¼±¼øÀ§ Á¤·ÄÀ» À§ÇØ pop()¿¡ ¹«¾ùÀÌ ÇÊ¿äÇÒ±î? ¼¼ °¡Áö ±âº»ÀûÀÎ °ÍÀÌ ÀÖ´Ù. ¿ì¼± pop()Àº Å¥(queue)¿¡ Àû¾îµµ ÇÑ °³ÀÇ ¿¤¸®¸ÕÆ®¶óµµ ¾ø´Ù¸é È£ÃâµÇ¾î¼­´Â ¾ÈµÈ´Ù. µÑ°, ³ôÀº ¿ì¼±¼øÀ§¸¦ °®°íÀִ ťÀÇ ¿¤¸®¸ÕÆ®¸¦ ¸®ÅÏÇؾßÇÑ´Ù. ¸¶Áö¸·À¸·Î, ÀÌ°ÍÀÌ ¸®ÅÏÇÏ´Â ¿¤¸®¸ÕÆ®¸¦ Å¥¿¡¼­ »èÁ¦ÇØ¾ß ÇÑ´Ù.

Listing 1Àº ù ¹ø° ÇÊ¿äÁ¶°ÇÀ» ³ªÅ¸³»´Â JML ÁÖ¼®ÀÌ´Ù:

Listing 1. pop() ¸Þ¼Òµå ¿ä±¸»çÇ×À» À§ÇÑ JML ÁÖ¼®


/*@
   @   public normal_behavior
   @     requires ! isEmpty();
   @*/
Object pop() throws NoSuchElementException;

¾Õ¼­ ¾ð±ÞÇÑ °Í ó·³ JML ÁÖ¼®Àº ÀÚ¹Ù ÁÖ¼® ¾È¿¡ ¾²¿©Áø´Ù. JMLÀ» Æ÷ÇÔÇÏ°í ÀÖ´Â ´ÙÁß ¶óÀÎ ÁÖ¼®Àº /*@·Î ½ÃÀÛÇÑ´Ù. JMLÀº //@·Î ½ÃÀÛÇÏ´Â ÇÑ ¶óÀÎÀÇ ÁÖ¼® ¾È¿¡ ¾²¿©Áú ¼öµµ ÀÖ´Ù.

public Å°¿öµå´Â JML°ú ÀÚ¹Ù ¸ðµÎ Àǹ̰¡ °°´Ù. publicÀº JML ½ºÆÑÀÌ ¾ÖÇø®ÄÉÀ̼ÇÀÇ ¸ðµç Ŭ·¡½º¿¡ º¸ÀÏ ¼ö ÀÖÀ½À» ³ªÅ¸³½´Ù. Public ½ºÆÑÀº public ¸Þ¼Òµå¿Í member º¯¼ö¸¦ ÀǹÌÇÑ´Ù.

normal_behavior Å°¿öµå´Â ÀÌ ½ºÆÑÀÌ pop()ÀÌ ¿¹¿Ü ¾øÀÌ Á¤»óÀûÀ¸·Î ¸®ÅÏÇÏ´Â °æ¿ì¸¦ ¼³¸íÇÑ´Ù.

»çÀü, »çÈÄ Á¶°Ç
JML Å°¿öµåÀÎ requires´Â »çÀüÁ¶°Ç(preconditions)¿¡ »ç¿ëµÈ´Ù. »çÀüÁ¶°Ç(precondition)Àº ¸Þ¼Òµå¸¦ È£ÃâÇϱâ Àü¿¡ ÃæÁ·µÇ¾îÁ®¾ß ÇÒ Á¶°ÇÀÌ´Ù.

¸Þ¼ÒµåÀÇ »çÈÄÁ¶°Ç(postcondition)Àº ¸Þ¼ÒµåÀÇ Ã¥ÀÓ¿¡ ´ëÇØ ¼³¸íÇÑ´Ù. ¸Þ¼Òµå°¡ ¸®ÅÏÇÏ¸é »çÈÄ Á¶°ÇÀº true°¡ µÈ´Ù. ¿¹Á¦¿¡¼­, pop()Àº °¡Àå ³ôÀº ¿ì¼±¼øÀ§¸¦ Áö´Ñ Å¥ÀÇ ¿¤¸®¸ÕÆ®¸¦ ¸®ÅÏÇØ¾ß ÇÑ´Ù. ÀÌ »çÈÄÁ¶°ÇÀ» ÁöÁ¤ÇÏ¿© JML¿¡ ÀÇÇØ °Ë»ç¹ÞÀ» ¼ö ÀÖµµ·Ï ÇÏ°í ½Í´Ù. À̸¦ À§Çؼ­´Â ¿ì¼±¼øÀ§ Å¥¿¡ ´õÇØÁø ¸ðµç °ªµéÀ» Áö¼ÓÀûÀ¸·Î Æ®·¡Å·ÇÑ´Ù. PriorityQueue¿¡ member º¯¼ö¸¦ Ãß°¡ÇÏ¿© Å¥¿¡ °ªÀ» ÀúÀåÇÏ´Â ¹æ¹ýÀ» °í·ÁÇÒ ¼öµµ ÀÖ´Ù. ÇÏÁö¸¸ ´ÙÀ½°ú °°Àº ¹®Á¦°¡ ÀÖ´Ù:

  • PriorityQueue´Â ÀÎÅÍÆäÀ̽ºÀÌ´Ù. µû¶ó¼­ ¹ÙÀ̳ʸ® Èü, Fibonacci Èü, Ķ¸°ÅÍ Å¥ °°Àº ´Ù¸¥ ±¸Çö°ú ȣȯµÇ¾î¾ß ÇÑ´Ù.PriorityQueue¿¡ ´ëÇÑ JML ÁÖ¼®Àº ±¸Çö¿¡ ´ëÇØ ¾î¶² Çؼ®µµ ¾ø´Ù.

  • ÀÎÅÍÆäÀ̽º·Î¼­ PriorityQueue´Â Á¤Àû member º¯¼ö¸¸ Æ÷ÇÔÇÒ ¼ö ÀÖ´Ù.

JMLÀº ¸ðµ¨ Çʵå(model fields) °³³äÀ¸·Î ÀÌ ¹®Á¦¸¦ ÇØ°áÇÑ´Ù.

¸ðµ¨ Çʵå(Model Fields)
¸ðµ¨ Çʵå´Â member º¯¼ö¿Í °°´Ù. ÀÌ°ÍÀº ÀÛµ¿ ½ºÆÑ¿¡ ¾²ÀÏ ¼ö ÀÖ´Ù. ´ÙÀ½Àº PriorityQueue¿¡ ¾²ÀÎ ¸ðµ¨ ÇÊµå ¼±¾ð ¿¹ÀÌ´Ù:


//@ public model instance JMLObjectBag elementsInQueue;

µ¥ÀÌÅÍ Å¸ÀÔÀÌ JMLObjectBagÀÎ elementsInQueue¶ó´Â ¸ðµ¨ Çʵ尡 ÀÖÀ½À» ÀÌ ¼±¾ðÀº ³ªÅ¸³»°í ÀÖ´Ù. instance Å°¿öµå´Â Çʵ尡 ÀÎÅÍÆäÀ̽º¿¡¼­ ¼±¾ðµÇ´õ¶óµµ ÇʵåÀÇ °³º°ÀûÀÎ ºñ-Á¤Àû Ä«ÇÇ´Â PriorityQueue¸¦ ±¸ÇöÇϴ Ŭ·¡½ºµéÀÇ °¢ ÀνºÅϽº¿¡ À§Ä¡ÇÒ °ÍÀÓÀ» ³ªÅ¸³»°í ÀÖ´Ù. ¸ðµç JML ÁÖ¼® ó·³ elementsInQueueÀÇ ¼±¾ðÀº ÀÚ¹Ù ÁÖ¼®¿¡ ³ªÅ¸³­´Ù.

½ºÆÑ vs. ±¸Çö

¿¤¸®¸ÕÆ®¸¦ ÀúÀåÇϱâ À§Çؼ­ bag À» »ç¿ëÇÑ´Ù´Â °ÍÀº ºñÈ¿À²ÀûÀÎ ÀÏÀÌ´Ù. ¿Ö³ÄÇÏ¸é ¸ðµç ¿¤¸®¸ÕÆ®´Â °¡Àå ³ôÀº ¿ì¼±¼øÀ§¸¦ °¡Áø °ÍÀ» ã±â À§ÇØ °Ë»çµÇ±â ¶§¹®ÀÌ´Ù. ÇÏÁö¸¸, bagÀº ±¸ÇöÀÇ ÀϺΰ¡ ¾Æ´Ñ ½ºÆÑÀÇ ÀϺÎÀÌ´Ù. ½ºÆÑÀÇ ¸ñÀûÀº PriorityQueueÀÇ ÀÛµ¿ ÀÎÅÍÆäÀ̽º¸¦ ¼³¸íÇÏ´Â °ÍÀÌ´Ù. ´Ù½Ã¸»Çؼ­ ÀÌ°ÍÀº Ŭ¶óÀ̾ðÆ®°¡ ÀÇÁöÇÒ ¼ö ÀÖ´Â ¿ÜºÎ ÀÛµ¿À̶ó´Â ¶æÀÌ´Ù. PriorityQueueÀÇ ±¸ÇöÀº ½ºÆÑ°ú °°Àº °á°ú¸¸ ³½´Ù¸é Á»´õ È¿À²ÀûÀÎ Á¢±Ù¹æ½ÄÀ» »ç¿ë ÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î JCCC¿¡´Â ¾î·¹ÀÌ¿¡ ÀúÀåµÈ ¹ÙÀ̳ʸ® ÈüÀ» »ç¿ëÇÏ¿© PriorityQueue¸¦ ±¸ÇöÇÏ´Â BinaryHeap Ŭ·¡½º°¡ Æ÷ÇԵǾî ÀÖ´Ù.

½ºÆÑÀÌ È¿À²ÀûÀ¸·Î ¾²¿©Áú ÇÊ¿ä°¡ ¾ø´õ¶óµµ JML ·±Å¸ÀÓ ¼±¾ð °Ë»çÀÚÀÇ È¿À²¼ºÀº Áß¿äÇÏ´Ù. ¿Ö³ÄÇϸé ÆÛÆ÷¸Õ½º¿¡ ¿µÇâÀ» ¹ÌÄ¡±â ¶§¹®ÀÌ´Ù.

elementsInQueue¿¡´Â ¿ì¼±¼øÀ§ Å¥¿¡ Ãß°¡µÈ °ªÀÌ Æ÷ÇԵǾî ÀÖ´Ù. Listing 2´Â pop()¿ë ½ºÆÑÀÌ elementsInQueue¸¦ ¾î¶»°Ô »ç¿ëÇÏ´ÂÁö º¸¿©ÁØ´Ù:

Listing 2. pop()ÀÇ »çÈÄÁ¶°Ç¿¡ »ç¿ëµÈ ¸ðµ¨ Çʵå


/*@
   @ public normal_behavior
   @   requires ! isEmpty();
   @   ensures
   @     elementsInQueue.equals(((JMLObjectBag)
   @          \old(elementsInQueue))
   @                        .remove(\result)) &&
   @     \result.equals(\old(peek()));
   @*/
Object pop() throws NoSuchElementException;

ensures Å°¿öµå´Â pop()ÀÌ ¸®ÅÏÇÒ ¶§ ÃæÁ·µÇ¾î¾ß ÇÏ´Â »çÈÄÁ¶°ÇÀ» °¡¸£Å°°í ÀÖ´Ù. \result´Â JML Å°¿öµå·Î¼­ pop()¿¡ ÀÇÇØ ¸®ÅÏµÈ °ª°ú °°´Ù. \old()´Â JML ÇÔ¼ö·Î¼­ pop()ÀÌ È£ÃâµÇ±â Àü¿¡ ÀÌ°ÍÀÇ ÀÎÀÚ°¡ °®°íÀÖ¾ú´ø °ªÀ» ¸®ÅÏÇÑ´Ù.

ensures Àý¿¡´Â µÎ °³ÀÇ »çÈÄÁ¶°ÇÀÌ ÀÖ´Ù. ù ¹ø°´Â pop()¿¡ ÀÇÇØ ¸®ÅÏµÈ °ªÀÌ elementsInQueue¿¡¼­ Á¦°ÅµÇ¾ú´Ù´Â °ÍÀ» ³ªÅ¸³½´Ù. µÎ ¹ø°´Â ¸®ÅÏ °ªÀÌ peek()¿¡ ÀÇÇØ ¸®ÅÏµÈ °ª°ú °°À½À» ³ªÅ¸³½´Ù.

Ŭ·¡½º ·¹º§ÀÇ ºÒº¯ °ª
JML¿¡¼­ ¸Þ¼Òµå¿ë »çÀü, »çÈÄ Á¶°ÇÀ» ÁöÁ¤ÇÏ´Â ¹æ¹ýÀ» ¹è¿ü´Ù. Ŭ·¡½º ·¹º§ÀÇ ºÒº¯ °ªµµ ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù. Ŭ·¡½º ·¹º§ÀÇ ºÒº¯ °ªÀº Ŭ·¡½ºÀÇ ¸ðµç ¸Þ¼ÒµåÀÇ ¿£Æ®¸®¿Í Ãⱸ ¿¡¼­ true À̾î¾ß ÇÑ´Ù.

¼ö·®È­(Quantification)
pop()ÀÇ ÀÌÀü ½ºÆÑ¿¡¼­ ÀÌ°ÍÀÇ ¸®ÅÏ °ªÀº peek()ÀÌ ¸®ÅÏÇÏ´Â °ª°ú µ¿ÀÏÇÏ´Ù°í ¸»ÇÑ ¹Ù ÀÖ´Ù. PriorityQueue¿¡¼­ peek()ÀÇ ½ºÆÑÀº Listing 3¿¡ ³ªÅ¸³ªÀÖ´Ù:

Listing 3. peek() ½ºÆÑ


/*@
   @ public normal_behavior
   @   requires ! isEmpty();
   @   ensures elementsInQueue.has(\result);
   @*/
/*@ pure @*/ Object peek() throws NoSuchElementException;

JML ÁÖ¼®Àº Å¥¿¡ Àû¾îµµ ÇϳªÀÇ ¿¤¸®¸ÕÆ®°¡ ÀÖÀ» ¶§ peek()ÀÌ È£ÃâµÇ¾î¾ß ÇÑ´Ù´Â °ÍÀ» ¸»ÇÏ°í ÀÖ´Ù. peek()¿¡ ÀÇÇØ ¸®ÅÏµÈ °ªÀº elementsInQueue¿¡ ÀÖ´Ù´Â °Íµµ ³ªÅ¸³»°í ÀÖ´Ù.

/*@ pure @*/ ÁÖ¼®Àº peek()ÀÌ ¼ø¼öÇÑ ¸Þ¼Òµå¶ó´Â °ÍÀ» ¸»ÇÏ°íÀÖ´Ù. ¼ø¼öÇÑ ¸Þ¼Òµå(pure method) ¶õ ºÎÀÛ¿ëÀÌ ¾ø´Â ¸Þ¼Òµå¶ó´Â °ÍÀ» ÀǹÌÇÑ´Ù. JMLÀº ¼ø¼ö ¸Þ¼Òµå¸¦ »ç¿ëÇÒ ¶§ ¼±¾ðÀ» Çã¿ëÇÑ´Ù.

»ó¼Ó

JML ½ºÆÑÀº ÀÎÅÍÆäÀ̽º¸¦ ±¸ÇöÇÏ´Â ¼­ºêŬ·¡½º¿Í Ŭ·¡½º¿¡ ÀÇÇØ »ó¼Ó¹Þ´Â´Ù. JML Å°¿öµåÀÎ also´Â Á¶»ó Ŭ·¡½º¿Í ±¸ÇöµÇ°í ÀÖ´Â ÀÎÅÍÆäÀ̽º ¿¡¼­ »ó¼Ó¹ÞÀº ½ºÆÑ°ú °áÇÕÇÑ´Ù´Â °ÍÀ» ³ªÅ¸³»°í ÀÖ´Ù. µû¶ó¼­ PriorityQueue ÀÎÅÍÆäÀ̽ºÀÇ peek()¿ë ½ºÆÑÀº BinaryHeapÀÇ peek()¿¡µµ Àû¿ëµÈ´Ù.

Min heap & max heap
peek()½ºÆÑ¿¡¼­ ÇÑ °¡Áö°¡ ºüÁ®ÀÖ´Ù. ¸®ÅÏ µÈ °ªÀÌ °¡Àå ³ôÀº ¿ì¼±¼øÀ§¸¦ °®°í ÀÖ´Ù´Â °ÍÀ» ³ªÅ¸³»Áö ¾Ê´Â´Ù. JCCCÀÇ PriorityQueue ÀÎÅÍÆäÀ̽º´Â min heap°ú max heap ¿ëÀ¸·Î ¾²ÀÏ ¼ö ÀÖ´Ù´Â °ÍÀ» ÀǹÌÇÑ´Ù. min heapÀÇ °æ¿ì °¡Àå ³ôÀº ¿ì¼±¼øÀ§ ¿¤¸®¸ÕÆ®´Â °¡Àå ÀÛÀº °ÍÀÌ°í ¹Ý¸é, max heapÀÇ °æ¿ì °¡Àå ³ôÀº ¿ì¼±¼øÀ§ ¿¤¸®¸ÕÆ®´Â °¡Àå Å« °ÍÀÌ´Ù. PriorityQueue°¡ min heap ¶Ç´Â max heap Áß ¾î¶² °Í°ú ÇÔ²² »ç¿ëµÉÁö ¸ð¸£±â ¶§¹®¿¡, ¾î¶² ¿¤¸®¸ÕÆ®°¡ ¸®ÅÏ µÉ Áö¸¦ ¼³¸íÇÏ´Â ½ºÆÑÀÇ ÀϺδ PriorityQueue¸¦ ±¸ÇöÇϴ Ŭ·¡½º·Î °¡¾ßÇÑ´Ù.

JCCC ¿¡¼­, BinaryHeap Ŭ·¡½º´Â PriorityQueue¸¦ ±¸ÇöÇÑ´Ù. BinaryHeapÀº Ŭ¶óÀ̾ðÆ®°¡ ±¸Á¶Ã¼ÀÇ ¸Å°³º¯¼ö¸¦ ÀÌ¿ëÇÏ¿© min heap ¶Ç´Â max heap Áß¿¡¼­ ÀÛµ¿À» Çϵµ·Ï ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù. ¿ì¸®´Â boolean ¸ðµ¨ º¯¼öÀÎ isMinimumHeap¸¦ »ç¿ëÇÏ¿© BinaryHeapÀÌ min heap ¶Ç´Â max heap Áß ¾î¶² °ÍÀ¸·Î ÀÛµ¿ÇÏ´ÂÁö ¼³¸íÇÒ ¼ö ÀÖ´Ù. BinaryHeapÀÇ peek() ½ºÆÑÀº isMinimumHeapÀ» »ç¿ëÇÑ´Ù. (Listing 4)

Listing 4. peek() ½ºÆÑ


/*@
   @ also
   @   public normal_behavior
   @     requires ! isEmpty();
   @     ensures
   @       (isMinimumHeap ==>
   @           (\forall Object obj;
   @                  elementsInQueue.has(obj);
   @                  compareObjects(\result, obj)
   @                             <= 0)) &&
   @       ((! isMinimumHeap) ==>
   @           (\forall Object obj;
   @                  elementsInQueue.has(obj);
   @                  compareObjects(\result, obj)
   @                             >= 0));
   @*/
public Object peek() throws NoSuchElementException

ÇÑÁ¤»ç Ãß°¡Çϱâ
Listing 4ÀÇ »çÈÄÁ¶°ÇÀº µÎ ºÎºÐ(min heap°ú max heap)À¸·Î ±¸¼ºµÇ¾î ÀÖ´Ù. ==> Ç¥½Ã´Â "ÇÔÃà(implies)"À̶ó´Â ÀǹÌÀÌ´Ù. x ==> y´Â y°¡ true À̰ųª x°¡ false ÀÏ °æ¿ì true ÀÌ´Ù. min heapÀÇ °æ¿ì ´ÙÀ½ Á¶°ÇÀÌ Àû¿ëµÈ´Ù:


(\forall Object obj;
          elementsInQueue.has(obj);
          compareObjects(\result, obj) <= 0)

comparator Ãß°¡Çϱâ
BinaryHeap Ŭ·¡½º´Â ¿¤¸®¸ÕÆ®µéÀÌ µÎ °¡Áö ´Ù¸¥ ¹æ½ÄÀ¸·Î ºñ±³µÉ ¼ö ÀÖµµ·Ï ÇÑ´Ù. ÇÑ °¡Áö Á¢±Ù ¹æ½ÄÀº Comparable ÀÎÅÍÆäÀ̽º¸¦ »ç¿ëÇÏ¿© ¿¤¸®¸ÕÆ®ÀÇ ¿ø·¡ ¼ø¼­¿¡ ÀÇÁ¸ÇÏ´Â °ÍÀÌ´Ù. ´Ù¸¥ Á¢±Ù ¹æ½ÄÀº Ŭ¶óÀ̾ðÆ®°¡ Comparable °´Ã¼¸¦ BinaryHeap ±¸Á¶Ã¼¿¡ Àü´ÞÇϵµ·Ï ÇÏ´Â °ÍÀÌ´Ù. ComparableÀº ¼ø¼­Á¤Çϱâ(ordering)¿¡ »ç¿ëµÉ ¼ö ÀÖ´Ù. ¾î·µç, ¸ðµ¨ ÇʵåÀÎ comparator¸¦ »ç¿ëÇÏ¿© Comparator °´Ã¼¸¦ ³ªÅ¸³¾ ¼ö ÀÖ´Ù. peek() »çÈÄ Á¶°Ç¿¡¼­ compareObjects() ¸Þ¼Òµå´Â Ŭ¶óÀ̾ðÆ®°¡ ¾î¶² ºñ±³ ¹æ½ÄÀ» äÅÃÇϵçÁö, äÅÃÇÑ °ÍÀ» »ç¿ëÇÑ´Ù.

Listing 5. compareObjects() ¸Þ¼Òµå


/*@
   @ public normal_behavior
   @   ensures
   @     (comparator == null) ==>
   @         (\result == ((Comparable) a).compareTo(b)) &&
   @     (comparator != null) ==>
   @         (\result == comparator.compare(a, b));
   @
   @ public pure model int compareObjects(Object a, Object b)
   @ {
   @ if (m_comparator == null)
   @     return ((Comparable) a).compareTo(b);
   @ else
   @     return m_comparator.compare(a, b);
   @ }
   @*/

modelÀº ¸ðµ¨ ¸Þ¼ÒµåÀÌ´Ù. Model method´Â ½ºÆÑ¿¡¸¸ »ç¿ëµÉ ¼ö ÀÖ´Â JML ¸Þ¼ÒµåÀÌ´Ù. ÀÚ¹Ù ÁÖ¼®¿¡¼­ ¼±¾ðµÇ¸ç Á¤½ÄÀÇ ÀÚ¹Ù ±¸Çö Äڵ忡´Â »ç¿ëµÉ ¼ö ¾ø´Ù.

BinaryHeapÀÇ Å¬¶óÀ̾ðÆ®°¡ ±¸Ã¼ÀûÀÎ Comparator°¡ »ç¿ëµÇ±â¸¦ ¿äûÇß´Ù¸é, m_comparator´Â Comparator¸¦ Áö½ÃÇÑ´Ù. ±×·¸Áö ¾ÊÀ¸¸é ¹«È¿°¡ µÈ´Ù. compareObjects()Àº m_comparatorÀÇ °ªÀ» °Ë»çÇÏ°í ÀûÀýÇÑ ºñ±³ ÀÛµ¿À» »ç¿ëÇÑ´Ù.

¸ðµ¨ Çʵ尡 °ªÀ» ¾ò´Â ¹æ¹ý
Listing 4¿¡¼­ peek()ÀÇ »çÈÄ Á¶°ÇÀ» ¼³¸íÇß´Ù. ÀÌ »çÈÄ Á¶°ÇÀº ¸®ÅÏ °ªÀÌ elementsInQueue ¸ðµ¨ Çʵ忡 ÀÖ´Â ¸ðµç ¿¤¸®¸ÕÆ®ÀÇ ¿ì¼±¼øÀ§ º¸´Ù Å©°Å³ª °°Àº ¿ì¼±¼øÀ§¸¦ °®°í ÀÖÀ½À» È®ÀÎÇÑ´Ù. ´ÙÀ½°ú °°Àº Áú¹®ÀÌ »ý±æ ¼ö ÀÖ´Ù. elementsInQueue °°Àº ¸ðµ¨ Çʵ尡 °ªÀ» ¾ò´Â ¹æ¹ýÀº? »çÀüÁ¶°Ç, »çÈÄÁ¶°Ç, ºÒº¯ °ªÀº ºÎÀÛ¿ëÀÌ ¾ø´Ù. µû¶ó¼­ ±×µéÀº ¸ðµ¨ ÇʵåÀÇ °ªÀ» ¼³Á¤ÇÒ ¼ö ¾ø´Ù.

JMLÀº represents ÀýÀ» »ç¿ëÇÏ¿© ¸ðµ¨ Çʵå¿Í ±¸Ã¼Àû ±¸Çö Çʵ带 °áÇÕÇÑ´Ù. ¿¹¸¦ µé¾î ´ÙÀ½ÀÇ represents ÀýÀº isMinimumHeap ¸ðµ¨ Çʵ忡 »ç¿ëµÈ´Ù.


//@ private represents isMinimumHeap <- m_isMinHeap;

¸ðµ¨ Çʵå isMinimumHeapÀÇ °ªÀÌ m_isMinHeapÀÇ °ª°ú °°´Ù´Â °ÍÀ» ³ªÅ¸³»°í ÀÖ´Ù. m_isMinHeapÀº BinaryHeap Ŭ·¡½º¿¡ ÀÖ´Â ÇÁ¶óÀ̺ø ºÎ¿ï member ÇʵåÀÌ´Ù. isMinimumHeap °ªÀÌ ¿äûµÇ¸é JMLÀº m_isMinHeap °ªÀ» ¾´´Ù.

represents ÀýÀº <-ÀÇ ¿À¸¥Æí¿¡ ÀÖ´Â member Çʵ忡 Á¦ÇѵǾî ÀÖÁö ¾Ê´Ù:

Listing 6. elementsInQueue ¿ë represents clause


/*@ private represents elementsInQueue
   @         <- JMLObjectBag.convertFrom(
   @                   Arrays.asList(m_elements)
   @                     .subList(1, m_size + 1));
   @*/

elementsInQueue´Â m_elements[]¿¡¼­ÀÇ °ª°ú °°´Ù. m_elements[]´Â BinaryHeapÀÇ ÇÁ¶óÀ̺ø member º¯¼öÀÌ´Ù. m_size´Â m_elements[]¿¡¼­ ÇöÀç »ç¿ëµÇ´Â ¿¤¸®¸ÕÆ®ÀÇ ¼ö ÀÌ´Ù. BinaryHeapÀº m_elements[0]¸¦ »ç¿ëÇÏÁö ¾Ê´Â´Ù. JMLObjectBag.convertFrom()Àº List¸¦ JMLObjectBagÀ¸·Î º¯È¯ÇÑ´Ù. ÀÌ°ÍÀº elementsInQueue¿¡ ÇÊ¿äÇÑ µ¥ÀÌÅÍ Å¸ÀÔÀÌ´Ù.

ºÎÀÛ¿ë
Listing 2ÀÇ pop()»çÈÄÁ¶°ÇÀ» ¶°¿Ã·Á º»´Ù:


ensures
elementsInQueue.equals(((JMLObjectBag)
             \old(elementsInQueue))
                           .remove(\result)) &&
\result.equals(\old(peek()));

pop()Àº elementsInQueue¿¡¼­ ¿¤¸®¸ÕÆ®¸¦ Á¦°ÅÇÏ´Â ºÎÀÛ¿ëÀ» °®°í ÀÖ´Ù. ÇÏÁö¸¸ ´Ù¸¥ ºÎÀÛ¿ëÀº ¾ø´Ù. ¿¹¸¦ µé¾î, pop()ÀÇ ±¸ÇöÀº min heap¿¡¼­ max heap À¸·Î ¹Ù²Ù±â À§ÇØ m_isMinHeap¸¦ º¯°æÇÒ ¼ö ÀÖ´Ù. ÀÌ·¯ÇÑ º¯°æÀº Á¤È®Àº °ªÀ» ¸®ÅÏÇÏ´Â ÇÑ ·±Å¸ÀÓ ¼±¾ð ¿À·ù¸¦ ¹ß»ý½ÃÅ°Áö ¾Ê´Â´Ù. ÇÏÁö¸¸ JML ½ºÆÑ Àüü¸¦ ¾àÈ­½Ãų ¼ö ÀÖ´Ù.

elementsInQueue¸¦ º¯°æÇÏ´Â °Í ¿Ü¿¡ ¶Ç ´Ù¸¥ ºÎÀÛ¿ëÀ» ÀÏÀ¸Å°Áö ¸øÇϵµ·Ï ÇÏ´Â »çÈÄ Á¶°ÇÀ» °­È­ÇÒ ¼ö ÀÖ´Ù. (Listing 7):

Listing 7. ºÎÀÛ¿ëÀ» À§ÇÑ »çÈÄÁ¶°Ç


ensures
elementsInQueue.equals(((JMLObjectBag)
            \old(elementsInQueue))
                           .remove(\result)) &&
\result.equals(\old(peek())) &&
isMinimumHeap == \old(isMinimumHeap) &&
comparator == \old(comparator);

x == \old(x)ÀÇ »çÈÄÁ¶°ÇÀ» Ãß°¡ÇÏ°í ÀÖ´Ù. ÀÌ·¯ÇÑ Á¢±Ù¹æ½ÄÀº °á±¹ ½ºÆÑÀ» ¾îÁö·´°Ô ¸¸µé »ÓÀÌ´Ù. ¶ÇÇÑ À¯Áöµµ ¾î·Á¿öÁø´Ù.

JMLÀº ¸Þ¼ÒµåÀÇ ºÎÀÛ¿ëÀ» ³ªÅ¸³»´Â º¸´Ù ³ªÀº ¹æ¹ýÀ» Á¦½ÃÇÑ´Ù.

assignable Àý
assignable ÀýÀº ¿ì¸®°¡ pop()¿ë ½ºÆÑÀ» ÀÛ¼ºÇÒ ¼ö ÀÖµµ·ÏÇÑ´Ù. (Listing 8)

Listing 8. assignable Àý

/*@
   @ public normal_behavior
   @   requires ! isEmpty();
   @   assignable elementsInQueue;
   @   ensures
   @     elementsInQueue.equals(((JMLObjectBag)
   @          \old(elementsInQueue))
   @                        .remove(\result)) &&
   @     \result.equals(\old(peek()));
   @*/
Object pop() throws NoSuchElementException;

assignable Àý¿¡ ³ª¿ÍÀÖ´Â Çʵ常 ¸Þ¼Òµå¿¡ ÀÇÇØ º¯°æµÉ ¼ö ÀÖ´Ù. pop()¿ë assignable ÀýÀº pop()ÀÌ elementsInQueue¸¦ º¯°æÇÒ ¼ö ÀÖÁö¸¸ isMinimumHeap À̳ª comparator °°Àº ´Ù¸¥ Çʵ带 º¯°æÇÒ ¼ö ¾øÀ½À» ¸»ÇØÁÖ°í ÀÖ´Ù. pop() ±¸ÇöÀÌ m_isMinHeapÀ» º¯°æÇÑ´Ù¸é ¿¡·¯°¡ ³¯ °ÍÀÌ´Ù.

À§Ä¡ º¯°æÇϱâ
½ÇÁ¦·Î´Â ´ÙÀ½°ú °°Àº ÆÑÅÍ°¡ true ÀÏ ¶§ ¸Þ¼Òµå°¡ À§Ä¡ (loc)¸¦ º¯°æÇÒ ¼ö ÀÖ´Ù:

  • locÀº assignable Àý¿¡ ¾ð±ÞµÈ´Ù.

  • assignable Àý¿¡ ¾ð±ÞµÈ À§Ä¡´Â loc¿¡ ÀÇÁ¸ÇÑ´Ù.

  • locÀº ¸Þ¼Òµå°¡ ½ÇÇàÀ» ½ÃÀÛÇϸé ÇÒ´çµÇÁö ¾Ê´Â´Ù.

  • locÀº ¸Þ¼ÒµåÀÇ ·ÎÄà º¯¼öÀ̰ųª ¸Þ¼ÒµåÀÇ Á¤½Ä ¸Å°³º¯¼öÀÌ´Ù.

¸¶Áö¸· °æ¿ì´Â ÀÎÀÚ°¡ assignable Àý¿¡ ³ªÅ¸³ªÁö ¾Ê´õ¶óµµ ¸Þ¼Òµå°¡ ÀÎÀÚ¸¦ º¯°æÇÒ ¼ö ÀÖ´Ù.

foo(Bar obj)°¡ obj.x = 17À» Æ÷ÇÔÇÏ°í ÀÖ´Ù¸é? È£Ãâ ÇÔ¼ö¿¡ º¸À̵µ·Ï º¯°æÀÌ µÉ ¼ö ÀÖ´Ù. ÇÏÁö¸¸ ¿©±â¿¡ ÇÔÁ¤ÀÌ ÀÖ´Ù. assignable Àý ±ÔÄ¢¿¡¼­´Â, assignable Àý¿¡ º¯¼ö¸¦ ¾ð±ÞÇÏÁö ¾Ê°í, ¸Þ¼Òµå°¡ »õ °ªÀ» ÀÎÀÚ¿¡ ÇÒ´çÇÒ ¼ö ÀÖ´Ù. ÇÏÁö¸¸ obj.x °°Àº ÀÎÀÚ Çʵ忡 »õ °ªÀ» ÇÒ´çÇÏ´Â °ÍÀ» Çã¿ëÇÏÁö ¾Ê´Â´Ù. foo()°¡ obj.x¸¦ º¯°æÇØ¾ß ÇÑ´Ù¸é assignable obj.x; Çü½ÄÀÇ assignable ÀýÀ» °¡Á®¾ß ÇÑ´Ù.

µÎ °³ÀÇ JML Å°¿öµå(\nothing & \everything)°¡ assignable Àý¿¡ »ç¿ëµÇ¾ú´Ù. assignable \nothingÀ» ÀÛ¼ºÇÏ¿© ¸Þ¼Òµå°¡ ºÎÀÛ¿ëÀ» °®°í ÀÖÁö ¾ÊÀ½À» ³ªÅ¸³¾ ¼ö ÀÖ´Ù. ÀÌ¿Í ºñ½ÁÇÏ°Ô assignable \everythingÀ» ÀÛ¼ºÇÔÀ¸·Î¼­ ¸Þ¼Òµå°¡ ¹«¾ùÀÌµç º¯°æÇÒ ¼ö ÀÖÀ½À» ³ªÅ¸³¾ ¼ö ÀÖ´Ù. ¾Õ¼­ ¾ð±ÞÇÑ ¼ø¼ö Å°¿öµå(pure keyword)´Â assignable \nothing;¿¡ ÇØ´çÇÑ´Ù.

¿¹¿Ü ÀÛµ¿
peek()°ú pop() ½ºÆÑÀº ¸Þ¼Òµå°¡ È£ÃâµÉ ¶§ Å¥°¡ ºñ¿öÁ®ÀÖ¾î¾ß ÇÑ´Ù. ½ÇÁ¦·Î peek()°ú pop()Àº Å¥°¡ ºñ¿öÁ® ÀÖÀ» ¶§ È£ÃâµÉ ¼ö ÀÖ´Ù. ±×¿Í °°Àº °æ¿ì ¸Þ¼Òµå´Â NoSuchElementExceptionÀ» ´øÁø´Ù. À̸¦ À§ÇØ ½ºÆÑÀ» ¼öÁ¤ÇØ¾ß ÇÑ´Ù. ±×¸®°í JMLÀÇ exceptional_behavior ÀýÀ» »ç¿ëÇÑ´Ù.

Áö±Ý ±îÁö ½ºÆÑÀº public normal_behavior·Î ½ÃÀÛÇß´Ù. normal_behavior Å°¿öµå´Â ÀÌ·¯ÇÑ ½ºÆѵéÀÌ ¸Þ¼Òµå°¡ ¾î¶² ¿¹¿Üµµ ´øÁöÁö ¾Ê´Â °æ¿ì¿¡ ´ëÇÑ ½ºÆÑÀÓÀ» ¶æÇÑ´Ù. public exceptional_behavior ÁÖ¼®Àº ¿¹¿Ü°¡ ´øÁ®Áú ¶§ ÀÛµ¿À» ¼³¸íÇϱâ À§ÇØ »ç¿ëµÈ´Ù.

Listing 9. exceptional_behavior ÁÖ¼®


/*@
   @ public normal_behavior
   @   requires ! isEmpty();
   @   ensures elementsInQueue.has(\result);
   @ also
   @ public exceptional_behavior
   @   requires isEmpty();
   @   signals (Exception e) e instanceof NoSuchElementException;
   @*/
/*@ pure @*/ Object peek() throws NoSuchElementException;

ÀÌ ½ºÆÑÀÇ Ã¹ ¹ø° ºÎºÐµµ public normal_behavior·Î ½ÃÀÛÇÑ´Ù. public exceptional_behavior·Î ½ÃÀÛÇÏ´Â µÎ ¹ø° ºÎºÐ¿¡¼­´Â ¿¹¿Ü ÀÛµ¿ÀÌ ¼³¸íµÈ´Ù. normal_behavior Àý°ú ¸¶Âù°¡Áö·Î, exceptional_behavior ÀýÀº requires ÀýÀ» °®°í ÀÖ´Ù. requires ÀýÀº signals Àý¿¡ ³ªÅ¸³ªÀÖ´Â ¿¹¿Ü°¡ ´øÁ®Áö±â À§Çؼ­ ¾î¶² Á¶°ÇÀÌ true°¡ µÇ¾î¾ß ÇÏ´ÂÁö¸¦ ³ªÅ¸³»°í ÀÖ´Ù. À§ ¿¹Á¦¿¡¼­, isEmpty()°¡ true À̸é peek()Àº NoSuchElementExceptionÀ» ´øÁø´Ù.

signals Àý
signals ÀýÀÇ ÀϹÝÀû ÇüÅ´ signals(E e) R; ÀÌ´Ù. JMLÀº signal ÀýÀ» ´ÙÀ½°ú °°ÀÌ ÀÎÅÍÇÁ¸®ÆÃÇÑ´Ù. E ŸÀÔÀÇ ¿¹¿Ü°¡ ´øÁ®Áö¸é JMLÀº RÀÌ true ÀÎÁö¸¦ °Ë»çÇÑ´Ù. ±×·¸°Ô µÇ¸é ¸Þ¼Òµå´Â ½ºÆÑÀ» ¸¸Á·½ÃŲ´Ù. RÀÌ false À̸é JMLÀº exceptional_behavior ½ºÆÑÀÌ À§¹ÝµÇ¾úÀ½À» ³ªÅ¸³»¸ç °Ë»çµÇÁö ¾ÊÀº ¿¹¿Ü¸¦ ´øÁø´Ù.

signals ÀýÀº Å¥°¡ ºñ¾úÀ»¶§ NoSuchElementExceptionÀÌ ³ª¿Í¾ß ÇÔÀ» ¿ä±¸ÇÏ°í ÀÖ´Ù. peek()ÀÌ ¿¹¿Ü¸¦ ´øÁö¸é JMLÀº ¿¡·¯·Î¼­ À̸¦ Àâ´Â´Ù. peek()ÀÌ NoSuchElementException À̳ª unchecked ¿¹¿Ü¸¦ ¸®ÅÏÇϵµ·Ï ÇÏ°í ½Í´Ù¸é, signals ÀýÀ» signals (NoSuchElementException e) true;·Î º¯°æÇÏ¸é µÈ´Ù.

Å¥¿¡ ¾î¶² °ÍÀÌ ÀÖ°í, ÀÌ°ÍÀÌ NoSuchElementExceptionÀ» ´øÁú ¶§peek()ÀÌ È£ÃâµÇ¸é, JML ·±Å¸ÀÓ ¼±¾ð °Ë»çÀÚ´Â Á¤»ó ÀÛµ¿ »çÈÄÁ¶°ÇÀÌ ½ÇÆÐÇß´Ù´Â °ÍÀ» ³ªÅ¸³»´Â unchecked exceptionÀ» ¹ß»ý½ÃŲ´Ù.

°á·Ð
ÀÌ ±Û¿¡ ´ëÇÑ »ó¼¼ ¼³¸íÀº Âü°íÀڷḦ ÅëÇØ °Ë»öÇϱ⠹ٶõ´Ù.

Âü°íÀÚ·á

¸ñ Â÷:
JML °³°ý
ÇÊ¿äÁ¶°Ç°ú Ã¥ÀÓ
¸ðµ¨ Çʵå
¼ö·®È­(Quantification)
¸ðµ¨ Çʵ尡 °ªÀ» ¾ò´Â ¹æ¹ý
ºÎÀÛ¿ë
¿¹¿Ü ÀÛµ¿
°á·Ð
Âü°í ÀÚ·á
ÇÊÀÚ ¼Ò°³
±â»ç¿¡ ´ëÇÑ Æò°¡
°ü·Ã dW ¸µÅ©:
Java modeling series
Subscribe to the developerWorks newsletter
US ¿ø¹® Àбâ
Also in the Java zone:
Tutorials
Tools and products
Code and components
Articles
ÇÊÀÚ¼Ò°³
Joe Verzulli´Â ÀÚ¹Ù ÄÁ¼³ÅÏÆ®ÀÌ´Ù.
ÀÌ ±â»ç¿¡ ´ëÇÏ¿© ¾î¶»°Ô »ý°¢ÇϽʴϱî?

Á¤¸» ÁÁ´Ù (5) ÁÁ´Ù (4) ±×Àú±×·¸´Ù (3) ¼öÁ¤º¸¿ÏÀÌ ÇÊ¿äÇÏ´Ù(2) ÇüÆí¾ø´Ù (1)

  È¸»ç¼Ò°³  |  °³ÀÎÁ¤º¸ º¸È£Á¤Ã¥  |  ¹ý·ü  |  ¹®ÀÇ