a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 115|回复: 1

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

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

使用道具 举报

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

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

  这两个文件都置于我自己系统的一个子目录中:
+ C6 |+ `2 N' O1 t  C:DOCJavaTcombruceeckelutil
% v& h# I! l$ S. a8 J  若经由过程它往回走,就会发现包名com.bruceeckel.util,但路径的第一部门又是什么呢?这是由CLASSPATH情形变量抉择的。在我的机械上,它是:
/ @, A1 Y7 M9 c/ ?* y0 M( U$ E  CLASSPATH=.;D:JAVALIB;C:DOCJavaT% D. S2 ?, ]! u! J" ]
  可以看出,CLASSPATH里能包含年夜量备用的搜索路径。然而,使用JAR文件时要注重矣闽问题:必需将JAR文件的名字置于类路径里,而不仅仅是它地址的路径。所以对一个名为grape.jar的JAR文件来说,我们的类路径需要搜罗:
: l7 M' l* E  B+ I5 o  CLASSPATH=.;D:JAVALIB;C:flavorsgrape.jar
9 s3 w, L4 ^/ p+ g' \  f& \* f& Y  正确设置好类路径后,可将下面这个文件置于任何目录里(若在执行该轨范时碰着麻烦,请参见第3章的3.1.2小节“赋值”):
6 P. T7 a4 r8 m0 `& b7 y6 R  //: LibTest.java; \. B* U$ B* I6 [
  // Uses the library
% ^# h# b% _/ N$ v& c! G  package c05;& F3 A6 O7 D, ^0 ?7 a
  import com.bruceeckel.util.*;
1 \& ^+ A/ }* S. \  public class LibTest {
) Z4 r% B, K% G, e( j; M0 B  A  public static void main(String[] args) {1 O5 e& p1 f& U# [/ y
  Vector v = new Vector();/ x+ D5 P3 e5 N9 {% q& w, R+ R
  List l = new List();
& p9 z" f5 X1 K: P; }4 B. q. Q/ Q  }
, F* P% W$ N1 U2 e* @  } ///:~
$ {& ^! V: ?. [& ], n  编译器碰着import语句后,它会搜索由CLASSPATH指定的目录,查找子目录combruceeckelutil,然后查找名称恰当的已编译文件(对于Vector是Vector.class,对于List则是List.class)。注重Vector和List内无论类仍是需要的体例都必需设为public。
( ]# ^; l( S1 v6 K, Q: Y  1. 自动编译9 J2 _' O4 H6 T# U+ U* L
  为导入的类初度建树一个对象时(或者访谒一个类的static成员时),编译器会在恰当的目录里寻找同名的.class文件(所以如不美观建树类X的一个对象,就应该是X.class)。若只发现X.class,它就是必需使用的那一个类。然而,如不美观它在不异的目录中还发现了一个X.java,编译器就会斗劲两个文件的日期标识表记标帜。如不美观X.java比X.class新,就会自动编译X.java,生成一个最新的X.class。: R6 v% o, B' c7 e
  对于一个特定的类,或在与它同名的.java文件中没有找到它,就会对阿谁类采纳上述的措置。
4 V! h- @6 J. c# j8 R  }/ g8 N9 ?  2. 冲突4 j' P( V4 n6 I
  若经由过程*导入了两个库,而且它们搜罗不异的名字,这时会呈现什么情形呢?例如,假定一个轨范使用了下述导入语句:4 @& C* V$ j) }6 T, X
  import com.bruceeckel.util.*;
- m2 B5 h# a" a' K6 a' n, s  import java.util.*;
! y+ k% t2 H# t/ p7 I  因为java.util.*也包含了一个Vector类,所以这会造成潜在的冲突。然而,只冲要突并不真的发生,那么就不会发生任何问题——这当然是最理想的情形,因为否则的话,就需要进行年夜量编程工作,提防那些可能可能永远也不会发生的冲突。) u/ I# Z0 I7 x' [
  如斯刻试着生成一个Vector,就必定会发生冲突。如下所示:
% K, `4 M: i7 q% F) g  Vector v = new Vector();" t; y! ~  J1 F
  它引用的到底是哪个Vector类呢?编译器对这个问题没有谜底,读者也不成能知道。所以编译器会陈述一个错误,强迫我们进行明晰的声名。例如,假设我想使用尺度的Java Vector,那么必需象下面这样编程:/ s8 j+ s+ o9 T: g- k
  java.util.Vector v = new java.util.Vector();- o. ?& F2 _6 N* z2 C, Y6 |1 D
  因为它(与CLASSPATH一路)完整指定了阿谁Vector的位置,所以不再需要import java.util.*语句,除非还想使用来自java.util的其他工具。
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-22 01:40 , Processed in 0.425429 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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