一、包
package p; public class SamePack { public static void main(String[] args) { } }
1、包的作用与声明
/* 包:包类似于操作系统中的文件夹。(类似,不是等同) 包的作用: 1 包可以提供文件(.class)的分类管理。 2 包可以提供独立的命名空间,进而解决命名冲突。 3 包可以提供访问权限的控制,实现更好的封装。 包的声明: package 包的名字。 以前我们没有显式的声明包,则文件处于无名包中。 包也可以具有层次性,包与包之间,包与类之间,使用 .进行分隔。 包声明的要求: 1 位置:包声明必须是源文件中第一条有效的语句。 2 数量:最多只能有一条包声明语句。 当显式声明包时,编译与运行与之前的细微变化: 编译: javac -d class文件的路径 源文件.java 运行: java 类的全限定名(包名 + 类名) 当两个类(A与B)处于同一个包中时,在A类型中 可以通过简单名来访问B。 当两个类(A与B)不在同一个包中时,则不能通过 简单名进行访问。此时,可以: 1 使用类的全限定名访问。 2 导入该类型,然后就可以通过简单名来访问。 import import 类的全限定名; import使用规则: 1 位置:import语句必须出现在包声明之后,类型 声明之前。 2 数量:import语句可以有0条到多条。 import 包名.*; 导入该包中所有的类型。(按需导入) 按需导入仅会导入当前包中的所有类型,不包括子包 中的类型。 import 包名.子包.*; java.lang包中的所有类会由编译器隐式的导入。 import java.lang.*; */ package p; //package p.subp; import p2.DiffPack; public class PackageTest { public static void main(String[] args) { //System.out.println("Hello World!"); //在同一包中,可以通过简单名来访问一个类。 new SamePack(); //不在同一个包中,不能通过简单名访问。 //new DiffPack(); //使用类的全限定名访问包外的类 new p2.DiffPack(); //通过import导入该类型后,可以使用类的简单名进行访问。 new DiffPack(); } } //错误。 //package p;
2、静态导入
/* import static 静态导入 import与import static import是导入一个(多个)类型,而import static 导入的是一个类型的成员(静态成员)。 当使用import static导入静态成员后,就可以直接 使用该静态成员(无需通过类名限定),就好像该 静态成员是当前类中所声明的一样。 */ import static java.lang.Math.sqrt; import static java.util.Arrays.*; public class ImportStatic { public static void main(String[] args) { int x = 100; System.out.println(Math.sqrt(x)); //直接访问静态成员,就像本类中声明的一样。 System.out.println(sqrt(x)); int[] k = {5, 4, 3, 2, 1}; sort(k); } }
3、
package in; /* 在类的内部,可以访问任意访问权限的成员变量。 因为在创建对象的时候,会自动调用构造器。 如果构造器没有访问权限,我们就无法成功创建对象。 */ public class PublicAc { public int pubX; int defX; private int priX; public void f() { pubX = 1; defX = 1; priX = 1; pubM(); defM(); priM(); new PublicAc(); new PublicAc(1); new PublicAc(1, 1); } public PublicAc() { } PublicAc(int x) { } private PublicAc(int x, int y) { } public void pubM() { } void defM() { } private void priM() { } } class DefAc { }
4、访问修饰符
访问修饰符用来声明访问权限,访问权限由高到低为: public 共有权限,全部对外开发。 protected 保护权限,对本包开放,对包外的子类开放。 不加修饰符限定 默认权限,对本包开放。 private 私有权限,仅对本类开放。 说明: 关于protected访问权限,推迟到继承的时候再说。 访问修饰符可以修饰类(接口),方法,成员变量,构造器。
/* 顶层类的访问权限可以是public与默认访问权限。 不可以是protected与private访问权限。 内部类可以是任意的访问权限。 在同一个包中,可以访问本包中声明为public,默认 访问权限的类。 在包外,可以访问声明为public访问权限类型。 */ package in; import out.*; /* 在类的外部,包的内部(同一个包中),可以访问 声明为public, 默认访问权限的成员,不能访问 声明为private访问权限的成员。 */ public class Access { public static void main(String[] args) { PublicAc p; DefAc d; PublicOut p2; //DefOut d2; PublicAc pa = new PublicAc(); pa.pubX = 1; pa.defX = 1; //pa.priX = 1; pa.pubM(); pa.defM(); //pa.priM(); new PublicAc(); new PublicAc(1); //new PublicAc(1, 1); } }
5、static 关键字
/* static关键字 static可以修饰类(内部类),成员变量,方法。 局部变量不能使用static修饰。 当static修饰成员变量时,该变量称为静态成员变量。 没有使用static修饰的成员变量称为实例成员变量。 当static修饰方法时,该方法称为静态方法。 没有使用static修饰的方法称为实例方法。 静态成员变量与实例成员变量 1 变量的数量 静态成员变量为整个类所有(整个类只有一个),如果 一个对象改变了静态成员变量的值,将会影响到其他对象 (其他对象看到的将是修改之后的结果)。 实例成员变量为对象所有,每个对象都有自己的实例成员 变量,一个对象改变了实例成员变量的值,对其他对象 没有影响。 2 变量的访问方式 静态成员变量既可以通过对象的引用进行访问(强烈不建议), 也可以通过类名进行访问。 实例成员变量只能通过对象的引用进行访问。 3 初始化的时间 静态成员变量会随着类的初始化而初始化。 实例成员变量在创建对象时得到初始化。 静态成员变量的初始化时间要早于实例成员变量。 */ public class Static { //实例成员变量 int x = 1; //静态成员变量 static int y = 2; public static void main(String[] args) { Static s = new Static(); Static s2 = new Static(); s.x = 100; //System.out.println(s2.x); //通过引用访问静态成员变量。(不推荐) s.y = 200; System.out.println(s2.y); //通过类名访问静态成员变量。 Static.y = 200; } }
6、
/* static修饰方法 静态方法与实例方法 1 方法的访问方式 静态方法既可以通过对象的引用来访问(强烈不推荐), 也可以通过类名来进行访问。 实例方法只能通过对象的引用进行访问。 2 成员的访问限制 静态方法只能访问静态成员(静态成员变量,静态方法等)。 实例方法既可以访问静态成员,也可以访问实例成员。 3 this与super 静态方法中不能使用this与super。 实例方法中可以使用this与super。 */ public class Static2 { int x = 1; static int y = 2; //实例方法 public void f() { x = 1; y = 2; g(); staticF(); } public void g() { } //静态方法 public static void staticF() { //错误,静态方法不能访问实例成员。 //x = 1; //g(); y = 2; staticG(); //Static2.staticG(); } public static void staticG() { } public static void main(String[] args) { Static2.staticF(); /* Static2 s = new Static2(); s.f(); //通过引用访问静态方法(不推荐) s.staticF(); //通过类名访问静态方法 Static2.staticF(); */ } }
7、
/* 静态成员变量的初始化 1 在变量声明处初始化 2 使用静态初始化块 两种初始化执行顺序与在类中声明的顺序一致。 (先声明的先执行) */ public class StaticInit { //静态初始化块 //在类初始化时会得到执行。 static { //x = 5; System.out.println("静态初始化块执行"); } //static int x = initX(); static int x; public StaticInit() { x = 100; } public static int initX() { System.out.println("x初始化执行"); return 1; } public static void main(String[] args) { System.out.println(x); } }
8、final 关键字
/* final可以修饰成员变量,局部变量,方法,类。 final修饰变量,该变量一经赋值,就不能够再进行修改。 final修改变量,该变量就会成为常量。 */ public class FinalTest { //final修饰成员变量时,需要进行显式的初始化, //不可以拿默认值作为初始值。 final int k; { //k = 2; } public FinalTest(int k) { this.k = k; } public static void main(String[] args) { final int x = 1; //x = 2; //final修饰一个局部变量,没有初始值,只要不使用 //该变量,就没有问题。 final int y; //x = 1; final int[] a = {1, 2, 3, 4, 5}; a[0] = 1000; System.out.println(a[0]); //a = #0x2345; //a = new int[3]; //a = null; } public void f(final int k) { //错误 //k = 2; } }
9、
/* final修饰变量的好处: 1 使用final修饰变量,可以防止变量被意外的进行修改。 2 使用final可以避免魔幻数字的产生,增加程序的可读性。 3 使用final可以提高程序的可维护性。 */ public class FinalAd { final int WIDTH = 10; final int HEIGHT = 5; public void compute() { //int area = 10 * 5; int area = WIDTH * HEIGHT; } }
10、private
/* 类的封装 隐藏底层的实现细节,将类中声明的成员变量私有化(private)。 提供公有getter与setter方法,供外界进行间接访问。 getter 获取成员变量的值。 setter 设置成员变量的值。 */ public class Private { //int x; => int x2; private int x2; public int getX() { return x2; } public void setX(int x) { this.x2 = x; } } class Another { public void access() { Private p = new Private(); //p.x = 1; p.setX(1); //System.out.println(p.x); System.out.println(p.getX()); } }