Download Java Package Tutorial

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Java Package Tutorial
(Thai version here)
by Patrick Bouklee
Introduction
Many times when we get a chance to work on a small project, one thing we intend to do is to put all java files
into one single directory. It is quick, easy and harmless. However if our small project gets bigger, and the
number of files is increasing, putting all these files into the same directory would be a nightmare for us. In
java we can avoid this sort of problem by using Packages.
Packages are nothing more than the way we organize files into different directories according to their
functionality, usability as well as category they should belong to. An obvious example of packaging is the
JDK package from SUN (java.xxx.yyy) as shown below:
Figure 1. Basic structure of JDK package
Basically, files in one directory (or package) would have different functionality from those of another
directory. For example, files in java.io package do something related to I/O, but files in java.net package give
us the way to deal with the Network. In GUI applications, it's quite common for us to see a directory with a
name "ui" (user interface), meaning that this directory keeps files related to the presentation part of the
application. On the other hand, we would see a directory called "engine", which stores all files related to the
core functionality of the application instead.
Packaging also help us to avoid class name collision when we use the same class name as that of others. For
example, if we have a class name called "Vector", its name would crash with the Vector class from JDK.
However, this never happens because JDK use java.util as a package name for the Vector class
(java.util.Vector). So our Vector class can be named as "Vector" or we can put it into another package
like com.mycompany.Vector without fighting with anyone. The benefits of using package reflect the ease of
maintenance, organization, and increase collaboration among developers. Understanding the concept of
package will also help us manage and use files stored in jar files in more efficient ways.
How to create a package
Suppose we have a file called HelloWorld.java, and we want to put this file in a package world. First thing
we have to do is to specify the keyword package with the name of the package we want to use (world in our
case) on top of our source file, before the code that defines the real classes in the package, as shown in our
HelloWorld class below:
// only comment can be here
package world;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
One thing you must do after creating a package for the class is to create nested subdirectories to represent
package hierachy of the class. In our case, we have the world package, which requires only one directory. So,
we create a directory world and put our HelloWorld.java into it.
Figure 2. HelloWorld in world package (C:\world\HelloWorld.java)
That's it!!! Right now we have HelloWorld class inside world package. Next, we have to introduce
the world package into our CLASSPATH.
Setting up the CLASSPATH
From figure 2 we put the package world under C:. So we just set our CLASSPATH as:
set CLASSPATH=.;C:\;
We set the CLASSPATH to point to 2 places, . (dot) and C:\ directory.
Note: If you used to play around with DOS or UNIX, you may be familiar with . (dot) and .. (dot dot). We
use . as an alias for the current directory and .. for the parent directory. In our CLASSPATH we include this . for
convenient reason. Java will find our class file not only from C: directory but from the current directory as
well. Also, we use ; (semicolon) to separate the directory location in case we keep class files in many places.
When compiling HelloWorld class, we just go to the world directory and type the command:
C:\world\javac HelloWorld.java
If you try to run this HelloWorld using java HelloWorld, you will get the following error:
C:\world>java HelloWorld
Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld (wrong name:
world/HelloWorld)
at java.lang.ClassLoader.defineClass0(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:442)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:101)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:248)
at java.net.URLClassLoader.access$1(URLClassLoader.java:216)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:191)
at java.lang.ClassLoader.loadClass(ClassLoader.java:290)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:286)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
The reason is right now the HelloWorld class belongs to the package world. If we want to run it, we have to
tell JVM about its fully-qualified class name (world.HelloWorld) instead of its plain class
name (HelloWorld).
C:\world>java world.HelloWorld
C:\world>Hello World
Note: fully-qualified class name is the name of the java class that includes its package name
To make this example more understandable, let's put the HelloWorld class along with its package (world) be
under C:\myclasses directory instead. The new location of our HelloWorld should be as shown in Figure 3:
Figure 3. HelloWorld class (in world package) under myclasses directory
We just changed the location of the package from C:\world\HelloWorld.java to
C:\myclasses\world\HelloWorld.java. Our CLASSPATH then needs to be changed to point to the new location
of the packageworld accordingly.
set CLASSPATH=.;C:\myclasses;
Thus, Java will look for java classes from the current directory and C:\myclasses directory instead.
Someone may ask "Do we have to run the HelloWorld at the directory that we store its class file
everytime?". The answer is NO. We can run the HelloWorld from anywhere as long as we still include the
package world in the CLASSPATH. For example,
C:\>set CLASSPATH=.;C:\;
C:\>set CLASSPATH // see what we have in CLSSPATH
CLASSPATH=.;C:\;
C:\>cd world
C:\world>java world.HelloWorld
Hello World
C:\world>cd ..
C:\>java world.HelloWorld
Hello World
Subpackage (package inside another package)
Assume we have another file called HelloMoon.java. We want to store it in a subpackage "moon", which
stays inside package world. The HelloMoon class should look something like this:
package world.moon;
public class HelloMoon {
private String holeName = "rabbit hole";
public getHoleName() {
return hole;
}
public setHole(String holeName) {
this.holeName = holeName;
}
}
If we store the package world under C: as before, the HelloMoon.java would
be c:\world\moon\HelloMoon.java as shown in Figure 4 below:
Figure 4. HelloMoon in world.moon package
Although we add a subpackage under package world, we still don't have to change anything in
our CLASSPATH. However, when we want to reference to the HelloMoon class, we have to
useworld.moon.HelloMoon as its fully-qualified class name.
How to use package
There are 2 ways in order to use the public classes stored in package.
1. Declare the fully-qualified class name. For example,
...
world.HelloWorld helloWorld = new world.HelloWorld();
world.moon.HelloMoon helloMoon = new world.moon.HelloMoon();
String holeName = helloMoon.getHoleName();
...
2) Use an "import" keyword:
import world.*; // we can call any public classes inside the world package
import world.moon.*; // we can call any public classes inside the world.moon package
import java.util.*; // import all public classes from java.util package
import java.util.Hashtable; // import only Hashtable class (not all classes in
java.util package)
Thus, the code that we use to call the HelloWorld and HelloMoon class should be
...
HelloWorld helloWorld = new HelloWorld(); // don't have to explicitly specify
world.HelloWorld anymore
HelloMoon helloMoon = new HelloMoon(); // don't have to explicitly specify
world.moon.HelloMoon anymore
...
Note that we can call public classes stored in the package level we do the import only. We can't use any
classes that belong to the subpackage of the package we import. For example, if we import package world,
we can use only the HelloWorld class, but not the HelloMoon class.
Using classes stored in jar file
Jar files are the place where we put a lot of files to be together. We compress these files and make them as a
single bundle. Jar files may also include directories, subdirectories to represent class and package hierachy.
Normally, we can see what is inside a jar file by using the command jar -tvf fileName.jar as shown in
Figure 5:
Figure 5. JSDK package viewed by jar -tvf jsdk.jar command
From figure 5 we see that there is a class called javax.servlet.http.Cookie. We can call this class by
import javax.servlet.http.Cookie; // import only Cookie class or
import javax.servlet.http.*; // import the whole javax.servlet.http package
But we have to include this package in the CLASSPATH as well.
set CLASSPATH=.;D:\JSDK2.0\lib\jsdk.jar;
Note that if the package is stored inside a jar file, we have to include the jar file with its extension (.jar) in
the CLASSPATH. However, if the package is a plain directory, we just put the name of directory into
the CLASSPATH.
Copyright (C) 2000-2001 www.jarticles.com.
Java Package Tutorial
(English version here)
โดย ประดับเก่ง
เกริ่นนํา
สําหรับคนที่ใช้จาว่าเขียนโปรเจคที่มีไฟล์มากกว่า 10 ไฟล์ข้ ึนไป สิ่ งที่ขาดไม่ได้อย่างหนึ่ งคือการแบ่งไฟล์ไว้ใน subdirectory ต่าง ๆ โดยแบ่งตาม
หมวดหมู่และความสามารถที่อยูใ่ นแต่ละไฟล์น้ นั ตัวอย่างที่เห็นได้ง่ายคือไฟล์ท้ งั หลายที่อยูใ่ น java package (java.xxx.yyy....)
รู ปที่ 1 โครงสร้างโดยทัว่ ไปของ java package
ไฟล์ที่อยูใ่ นแต่ละ subdirectory จะมีหน้าที่แตกต่างกัน ยกตัวอย่างไฟล์ใน java.io.*; จะทําหน้าที่เกี่ยวกับ Input/Output ไฟล์ที่อยู่
ใน java.net.*; ก็จะทําหน้าที่เกี่ยวกับ network เป็ นต้น ถ้าใครเคยเข้าไปดู directory ใน java application ที่มี
graphical user interface (GUI) รวมอยูด่ ว้ ย ก็มกั จะเห็น subdirectory ที่มีชื่อว่า ui (user interface)
ซึ่ งเป็ นที่ ๆ เก็บโค๊ดเกี่ยวกับ GUI ทั้งหมด กับ engine ซึ่ งเป็ นส่ วนที่เก็บโค๊ดที่เป็ นตัวทํางานจริ ง ๆ เมื่อ user กดที่ปุ่มต่าง ๆ
ประโยชน์ที่เห็นได้ชดั ในการใช้ package คือ การง่ายในการจัดเก็บ ค้นหา รวมไปถึงการแบ่งแยกไฟล์ในแต่ละโปรเจคให้แยกจากกันโดยสิ้ นเชิ ง ความเข้าใจ
เกี่ยวกับ package จะช่วยให้สามารถใช้ไฟล์ที่เก็บอยูใ่ น .jar (java archive) ไฟล์ ซึ่งนักพัฒนานํามาจากที่ต่าง ๆ ได้อย่างเหมาะสมมากขึ้น
การเขียน package
สมมุติวา่ มีไฟล์หนึ่งชื่อ HelloWorld ซึ่ งเราอยากให้อยูใ่ น package ทีชื่อว่า world เราจะต้องใส่คาํ ว่า package world ไว้บนสุ ดของไฟล์
HelloWorld
//================HelloWorld.java====================
package world;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
//===================================================
สิ่ งหนึ่ งที่จะลืมไม่ได้หลังจากจัดให้ไฟล์ HelloWorld อยูใ่ น package ที่ชื่อ world แล้ว คือการนําไฟล์น้ นั ไปใส่ ใน directory ที่มีชื่อว่า
world ง่ายที่สุดคือการใส่ ไว้ที่ root directory ดังนั้นโครงสร้างของ package ก็จะเป็ นดังรู ป
C:\world\HelloWorld.java
รู ปที่ 2 class HelloWorld ซึ่งอยูใ่ น "world" package
ถ้าจะให้ javac (java compiler) หรื อ java (Java virtual machine) เห็น package นี้ เราจะต้องทําอีกอย่างคือ
การเซ็ต CLASSPATH
set CLASSPATH=.;C:\;
ในตัวอย่างนี้ จาวาจะหาไฟล์ HelloWorld ที่อยูใ่ น package "world" = world.HelloWorld จาก directory ปั จจุบนั
กับ C:\ drive
. หมายถึง directory ปั จจุบนั
C:\ คือ directory ที่เราเก็บ package ไว้ อาจมี ; กั้น ถ้ามีการเซ็ต classpath ให้หาหลาย ๆ ที่
ถ้าไม่อยากใส่ไว้ที่ root แต่อยากใส่ไว้ที่ directory ที่ชื่อ myclasses โครงสร้างของ package ก็จะเป็ นดังรู ป
C:\myclasses\world\HelloWorld.java
รู ปที่ 3 class HelloWorld ซึ่ งอยูใ่ น "world" package แต่เก็บไว้ใน myclasses directory
การเซ็ต classpath ก็จะเปลี่ยนเป็ น
set classpath = .;C:\myclasses;
จาว่าก็จะหาไฟล์ world.HelloWorld จาก directory ปั จจุบนั กับ C:\myclasses directory แทน
ถ้าจะ compile ก็ให้ไปที่ directory C:\myclasses\world\ แล้วพิมพ์ javac HelloWorld.java
ถ้าจะ run ก็จะต้องใส่ชื่อแบบเต็มรู ปแบบคือ java world.HelloWorld
บางทีใน package อาจมีการเก็บไฟล์ไว้ในหลาย level สมมุติวา่ เราอยากสร้างไฟล์ชื่อ HelloMoon ไว้ ใน subpackage ชื่ อ moon ซึ่ ง
อยูข่ า้ งใน package "world" อีกที ไฟล์ HelloMoon ก็จะเป็ นดังนี้
//=================HelloMoon.java====================
package world.moon;
public class HelloMoon {
protected String holeName = "rabbit hole";
public String getHoleName() {
return hole;
}
public void setHole(String holeName) {
this.holeName = holeName;
}
}
//===================================================
ถ้าเราเริ่ มจาก root directory ไฟล์ HelloMoon ก็จะเป็ น c:\world\moon\HelloMoon.java
รู ปที่ 4 class HelloMoon ซึ่งอยูใ่ น "world.coom" package
การเซ็ต classpath ก็เหมือนเดิมคือ
set classpath = .;C:\;
ที่เป็ นดังนี้ เพราะไฟล์ HelloMoon อยูใ่ น package ชื่อ world.moon ถ้าเราย้าย classpath จาก .;C:\; เป็ น .;C:\world;
จาว่าจะเห็นว่าไฟล์ HelloMoon อยูใ่ น package ชื่อ moon แทน
การใช้ package
การเรี ยกใช้ class ที่เป็ น public จาก package ต่าง ๆ (ถ้าดูจากตัวอย่างข้างต้น ก็จะเป็ นไฟล์ HelloWorld กับ HelloMoon) อาจทําได้
สองวิธีคือ
1) เรี ยกชื่อเต็มโดยตรง ยกตัวอย่างเช่น
world.HelloWorld helloWorld = new world.HelloWorld();
world.moon.HelloMoon helloMoon = new world.moon.HelloMoon();
String holeName = helloMoon.getHoleName();
...
2) โดยการใช้ import
import world.*; // สามารถเรี ยกทุก class ใน world package ที่เป็ น public มาใช้ได้ (แต่เรามีไฟล์เดียว คือ
HelloWorld.java)
import world.moon.*; // สามารถนําทุกไฟล์ใน world.moon package ที่เป็ น public มาใช้ได้ (มีไฟล์เดียว คือ
HelloMoon)
ข้อสังเกตุที่เห็นคือ ถ้าเรา import แค่ package "world" เราจะไม่สามารถเรี ยกไฟล์ที่อยูใ่ น subpackage moon มาใช้ได้
ถ้าเรา import แค่ package "world.moon" เราก็ไม่สามารถเรี ยก class HelloWorld มาใช้ได้เช่นกัน บางทีเราอาจจะชี้ เฉพาะ class
ที่เราอยากเรี ยกใช้โดยไม่ครอบคลุมทั้ง package. import ก็อาจจะเป็ น
import java.net.URL; // class ที่เราสามารถใช้ได้จะมีเพียง class URL
ข้อดีของ java คือ ไม่วา่ เราจะ import ทั้ง package หรื อเฉพาะไฟล์ เวลาในการ compile หรื อ ขนาดของโปรแกรมก็จะไม่เปลี่ยนแปลง
การเรียกใช้ class ใน .jar ไฟล์
jar ไฟล์คือไฟล์ที่รวบรวมไฟล์หลาย ๆ ไฟล์เข้าด้วยกัน โดยโครงสร้างอาจจะประกอบด้วยหลาย ๆ directory รวมไปถึง subdirectory ซึ่ งจริ ง
ๆ แล้วก็คือ package นัน่ เอง
วิธีดูวา่ ใน .jar ไฟล์ มีอะไรอยูบ่ า้ ง ให้ใช้ jar -tvf xxx.jar ยกตัวอย่างเช่น
รู ปที่ 5 โครงสร้างของ jsdk package เมื่อใช้ jar -tvf jsdk.jar
จากรู ป หลังจากที่เราดูโครงสร้างของไฟล์ jsdk.jar แล้ว สมมุติวา่ เราจะเรี ยกใช้ class ที่ชื่อ Cookie (บรรทัดที่ 4) เราสามารถเรี ยกใช้ได้โดย
import javax.servlet.http.Cookie; หรื อ
import javax.servlet.http.*;
// import ทัง้ package
ถ้า compile จาว่าอาจจะมองไม่เห็น package นี้ ดังนั้นเราต้อง
set classpath = .;D:\JSDK2.0\lib\jsdk.jar;
เราจะสังเกตุได้วา่ ถ้า package ถูกแพ๊คอยูใ่ นรู ปของ .jar ไฟล์ เวลา set classpath เราจะต้องใส่ ชื่อ .jar ไฟล์น้ นั ลงไป แต่ถา้
package นั้นถูก unpack จาก .jar ไฟล์ หรื อ อยูใ่ น directory เฉย ๆ เวลาเรา set classpath เราจะใส่ แค่ชื่อ
directory ที่เก็บ package นั้น