a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 116|回复: 1

[其他] JAVA技巧:教你如何创建独一无二的包名

[复制链接]
发表于 2012-8-4 12:28:23 | 显示全部楼层 |阅读模式
巨匠或许已注重到这样一个事实:因为一个包永远不会真的“封装”到零丁一个文件琅缦沔,它可由多个.class文件组成,所以场所排场可能稍微有些杂乱。为避免这个问题,最合理的一种做法就是将某个特定包使用的所有.class文件都置入单个目录里。也就是说,我们要操作操作系统的分级文件结构避免呈现杂乱场所排场。这恰是Java所采纳的体例。
: r# y. X* ]# f' M% ^  它同时也解决了另两个问题:建树并世无双的包名以及找出那些可能深藏于目录结构某处的类。正如我们在第2章讲述的那样,为达到这个目的,需要将.class文件的位置路径编码到package的名字里。但按照商定,编译器强迫package名的第一部门是类建树者的因特网域名。因为因特网域名必定是并世无双的(由InterNIC保证——注释②,它节制着域名的分配),所以假如按这一商定行事,package的名称就必定不会一再,所以永远不会碰知名称冲突的问题。换句话说,除非将自己的域名让渡给其他人,而且对方也按照不异的路径名编写Java代码,否则名字的冲突是永远不会呈现的。当然,如不美观你没有自己的域名,那么必需缔造一个很是生僻事包名(例如自己的英文姓名),以便尽最年夜可能建树一个并世无双的包名。现在择刊行自己的Java代码,那么强烈举荐去申请自己的域名,它所需的费用长短常低廉的。
- b9 \3 D6 {8 v/ v6 F. ^  ②:ftp://ftp.internic.net3 M/ [5 G+ ^9 ]  n. y7 v- _
  这个技巧的另一部门是将package名解析成自己机械上的一个目录。这样一来,Java轨范运行并需要装载.class文件的时辰(这是动态进行的,在轨范需要建树属于阿谁类的一个对象,或者初度访谒阿谁类的一个static成员时),它就可以找到.class文件驻留的阿谁目录。
( [- q' ^( F. u; o+ S; {  Java诠释器的工作轨范如下:首先,它找到情形变量CLASSPATH(将Java或者具有Java诠释能力的工具——如浏览器——安装到机械中时,经由过程操作系统进行设定)。CLASSPATH包含了一个或多个目录,它们作为一种非凡的“根”使用,年夜这里睁开对.class文件的搜索。年夜阿谁根起头,诠释器会寻找包名,并将每个点号(句点)替代成一个斜杠,年夜而生成年夜CLASSPATH根起头的一个路径名(所以package foo.bar.baz会酿成foobarbaz或者foo/bar/baz;具体是正斜杠仍是反斜杠由操作系统抉择)。随后将它们毗连到一路,成为CLASSPATH内的各个条目(进口)。往后搜索.class文件时,就可年夜这些处所起头查找与筹备建树的类名对应的名字。此外,它也会搜索一些尺度目录——这些目录与Java诠释器驻留的处所有关。
) W# r  l* e! {, }4 o6 w; j$ o  为进一步理解这个问题,下面以我自己的域名为例,它是bruceeckel.com。将其反转过来后,com.bruceeckel就为我的类建树了并世无双的全局名称(com,edu,org,net等扩展名以前在Java包中都是年夜写的,但自Java 1.2以来,这种情形已发生了转变。此刻整个包名都是小写的)。因为抉择建树一个名为util的柯棘我可以进一步地朋分它,所以最后获得的包名如下:/ k# \. d" V; P9 G) w' z
  package com.bruceeckel.util;
6 `3 Q+ A, |( f- z  y5 v* I" S. p  此刻,可将这个包名作为下述两个文件的“命名空间”使用:
4 c* @: ~& {/ v3 J" u1 l0 B( ^$ d  //: Vector.java
# p' r# T8 R1 `- l+ o6 B% E4 W  // Creating a package
& s9 w. Z; A  A5 v; e  package com.bruceeckel.util;
0 n3 [% h+ Y4 b$ a, n/ o- b% y& E- O9 K  public class Vector {
# F' Q. k0 X6 ]; v! K) Z  public Vector() {! \$ z; y* q$ `" b6 N5 L' z
  System.out.println(
$ v5 i0 D& E+ q+ G1 i  "com.bruceeckel.util.Vector");4 D5 M4 ~8 w4 v/ ?& y
  }
9 {6 Y" }: r5 y9 W) x  } ///:~7 A: l# k5 J, m
  建树自己的包时,要求package语句必需是文件中的第一个“非注释”代码。第二个文件概况看起来是近似的:
* Z4 d" M4 u% ]& ?& @/ \8 r, P  //: List.java  Q: i, }: i6 [+ V
  // Creating a package* k; B) y/ w: F$ O+ g
  package com.bruceeckel.util;9 j( Q) R* C) e( M7 [) `
  public class List {! r) y2 V2 Q+ \2 E8 @0 H2 p0 g' N
  public List() {
; F8 [- @1 ]  U+ i3 C7 O. B  System.out.println(9 }8 w4 o# {: {+ y1 }7 Z* _$ _
  "com.bruceeckel.util.List");
9 @, l4 I! h2 y3 c8 q  }; t6 P9 `; E+ _- S+ H" u
  } ///:~
回复

使用道具 举报

 楼主| 发表于 2012-8-4 12:28:24 | 显示全部楼层

JAVA技巧:教你如何创建独一无二的包名

  这两个文件都置于我自己系统的一个子目录中:
1 c; G3 M3 s% h) ^  C:DOCJavaTcombruceeckelutil
; c8 r% m, O$ m+ z3 w1 \1 [2 @2 w  若经由过程它往回走,就会发现包名com.bruceeckel.util,但路径的第一部门又是什么呢?这是由CLASSPATH情形变量抉择的。在我的机械上,它是:( |3 I% N( T* G2 G; ?
  CLASSPATH=.;D:JAVALIB;C:DOCJavaT
% z# p! [" D6 \  可以看出,CLASSPATH里能包含年夜量备用的搜索路径。然而,使用JAR文件时要注重矣闽问题:必需将JAR文件的名字置于类路径里,而不仅仅是它地址的路径。所以对一个名为grape.jar的JAR文件来说,我们的类路径需要搜罗:
' {- D- V, G$ E% A% U! m  CLASSPATH=.;D:JAVALIB;C:flavorsgrape.jar8 e1 z/ N5 M1 n# m
  正确设置好类路径后,可将下面这个文件置于任何目录里(若在执行该轨范时碰着麻烦,请参见第3章的3.1.2小节“赋值”):" s! d4 E& N0 f0 |0 r( v) S# X1 y
  //: LibTest.java
) V- F5 F( g' N1 b" G# H/ Z  // Uses the library
" e3 v) S/ U! x  o8 @5 \: f% l' k- x  package c05;
/ k( o1 b' u! T  import com.bruceeckel.util.*;1 M$ L) Z  o; r' P7 F
  public class LibTest {
; j+ B5 v/ @0 p+ \1 ^  public static void main(String[] args) {# n4 S7 w3 M! n+ q7 x. [; H
  Vector v = new Vector();# Q# ~. _% I2 Z& n
  List l = new List();! Q, l" ?% b2 i+ V/ i# }( D
  }* W1 |5 ~; w8 x% \# E3 h5 P
  } ///:~0 X' F+ u0 x$ c
  编译器碰着import语句后,它会搜索由CLASSPATH指定的目录,查找子目录combruceeckelutil,然后查找名称恰当的已编译文件(对于Vector是Vector.class,对于List则是List.class)。注重Vector和List内无论类仍是需要的体例都必需设为public。$ K% `5 g3 E3 J: Z& y7 {
  1. 自动编译6 c! \8 j$ Z$ I) i+ \' \) U, a# w
  为导入的类初度建树一个对象时(或者访谒一个类的static成员时),编译器会在恰当的目录里寻找同名的.class文件(所以如不美观建树类X的一个对象,就应该是X.class)。若只发现X.class,它就是必需使用的那一个类。然而,如不美观它在不异的目录中还发现了一个X.java,编译器就会斗劲两个文件的日期标识表记标帜。如不美观X.java比X.class新,就会自动编译X.java,生成一个最新的X.class。: A4 C+ O$ [( ]
  对于一个特定的类,或在与它同名的.java文件中没有找到它,就会对阿谁类采纳上述的措置。
# \- c! J6 W7 k3 M! j  2. 冲突
/ F* ?0 X; e% q# Q  若经由过程*导入了两个库,而且它们搜罗不异的名字,这时会呈现什么情形呢?例如,假定一个轨范使用了下述导入语句:2 d( ]7 Y$ v8 q9 l2 f9 t7 @! B
  import com.bruceeckel.util.*;( _, ]7 @3 {3 ^3 n! d& o0 x5 R8 `
  import java.util.*;
$ r" \7 c/ y, j4 L; N  因为java.util.*也包含了一个Vector类,所以这会造成潜在的冲突。然而,只冲要突并不真的发生,那么就不会发生任何问题——这当然是最理想的情形,因为否则的话,就需要进行年夜量编程工作,提防那些可能可能永远也不会发生的冲突。
. W, Y1 E) [& P5 d8 \  如斯刻试着生成一个Vector,就必定会发生冲突。如下所示:7 H& x& P  m0 M. F) x% r
  Vector v = new Vector();: `, Y7 s0 q1 [! d
  它引用的到底是哪个Vector类呢?编译器对这个问题没有谜底,读者也不成能知道。所以编译器会陈述一个错误,强迫我们进行明晰的声名。例如,假设我想使用尺度的Java Vector,那么必需象下面这样编程:
" B4 y- e, s1 Y( L  java.util.Vector v = new java.util.Vector();
2 A& Y6 t# o, J  j4 M+ {  因为它(与CLASSPATH一路)完整指定了阿谁Vector的位置,所以不再需要import java.util.*语句,除非还想使用来自java.util的其他工具。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-6-9 07:15 , Processed in 0.321071 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表