包的命名规则:
包名全部由小写字母(多个单词也全部小写);
如果包名包含多个层次,每个层次应该用“.”分割;
报名一般由倒置的域名开头,比如com.baidu.www;
自定义包不能java开头;
a、 package语句用于指明该源文件定义的类所在的包。一个Java源文件中最多只能有一条package语句;
b、如果Java源文件中有package语句,则该语句一定是源文件中的第一条可执行语句,它的前面只能有注释或空行;
包的作用:
有利于类的查找与管理。一个软件由很多类构成,这些类按其功能可分为vo类、dao类、工具类、service类、controller类等,将这些类按其功能分门别类地放在不同包中有利于类的查找与管理;
解决了同名类命名冲突;
有利于保护类中的成员变量及其方法。类中成员变量及其方法前面的访问控制符决定了该变量和方法的使用范围
定义包用package关键字:
1:对类文件进行分类管理。
2:给类文件提供多层名称空间。
类的全名称:
包名.类名
编译命令:javac –d 位置(.当前路径) java源文件 (就可以自动生成包)
包是一种封装形式:
用于封装类,想要被包以外的程序访问,该类必须public;
类中的成员,如果被包以外访问,也必须public;
导包的原则:
用到哪个类,就导入哪个类。
import :
为了简化类名书写。
JDK中的包
JDK类库中的包,最高一级的包名是java和javax。
java.lang:提供利用 Java 编程语言进行程序设计的基础类,例如:String、Math、Integer、System和Thread等。
java.util:java工具类,包含对集合的操作、事件模型、日期和时间设施、国际化和各种实用工具类。
java.io:通过数据流、序列化和文件系统提供系统输入和输出。
java.net:为实现网络应用程序提供类。
java.awt:包含用于创建用户界面和绘制图形图像的所有类。
什么时候需要引包:
自定义类中使用在不同一包中的其它自定义类时;
自定义类中除java.lang包以外的其它包中的JDK中自带的类时就需要引包;
自定义类中使用其它第三方jar包中的类或接口时需要引包;
如何引包,引包的方式有两种:
直接使用完整类名引包;
使用import关键字引包;
使用import关键字将其它包中的类引入到当前类中有两种方法:
import 包名.类名,这种方式用的最多;
import 包名.*,这种方式将向类中导入该包中的所有公共类;
包与包之间的类进行访问:
被访问的包中的类必须是public的,被访问的包中的类的方法也必须是public的。
访问修饰符
软件中的某些属性和方法出于程序安全考虑不允许被其它类操作和调用,这就需要使用Java中的访问权限修饰符,Java中的访问权限修饰符有4中:
Java中的访问权限修饰符可以修饰成员变量、构造方法、普通方法。
Public:
是最大的访问权限修饰符,其修饰的成员变量、构造方法和普通方法可在任何一个类中被操作或使用;
Protected
修饰的成员变量、构造方法和普通方法可以在其定义类中、与定义类同包的其它类(可以使子类)中和与定义类不同包但是其子类的类中使用;
默认(友好的)
修饰的成员变量、构造方法和普通方法可以在其定义类中和与定义类同包的其它类(可以使子类)中使用;
Private
是最小的访问权限控制符,其修饰的成员变量、构造方法和普通方法只能在定义它们的类中被操作或使用;
访问控制修饰符 | 当前定义类的内部 | 同一个包 其它类中 | 不同包的 子类中 | 不同包的 非子类中 |
public | √ | √ | √ | √ |
protected | √ | √ | √ | |
default | √ | √ | ||
private | √ |
非访问修饰符
为了实现一些其他的功能,Java 也提供了许多非访问修饰符。
static 修饰符,用来修饰类方法和类变量。
final 修饰符,用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
abstract 修饰符,用来创建抽象类和抽象方法。
synchronized 和 volatile 修饰符,主要用于线程的编程。
static 修饰符
静态变量:
static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。 静态变量也被称为类变量。局部变量不能被声明为 static 变量。类所有的实例都共享静态变量,可以直接通过类名来访问它。
实例变量:每创建一个实例就会产生一个实例变量,它与该实例同生共死。
public class A {
private int x; // 实例变量
private static int y; // 静态变量
public static void main(String[] args) {
// int x = A.x; // Non-static field 'x' cannot be referenced from a static context
A a = new A();
int x = a.x;
int y = A.y;
}
}
静态方法:
static 关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据,然后计算这些数据。静态方法在类加载的时候就存在了,它不依赖于任何实例。所以静态方法必须有实现,也就是说它不能是抽象方法。
对类变量和方法的访问可以直接使用 classname.variableName 和 classname.methodName 的方式访问。
如下例所示,static修饰符用来创建类方法和类变量。
public class InstanceCounter {
private static int numInstances = 0;
protected static int getCount() {
return numInstances;
}
private static void addInstance() {
numInstances++;
}
InstanceCounter() {
InstanceCounter.addInstance();
}
public static void main(String[] arguments) {
System.out.println("Starting with " + InstanceCounter.getCount() + " instances");
for (int i = 0; i < 500; ++i){
new InstanceCounter();
}
System.out.println("Created " + InstanceCounter.getCount() + " instances");
}
}
以上实例运行编辑结果如下:
Starting with 0 instances
Created 500 instances
只能访问所属类的静态字段和静态方法,方法中不能有 this 和 super 关键字,因此这两个关键字与具体对象关联。
public class A {
private static int x;
private int y;
public static void func1(){
int a = x;
// int b = y; // Non-static field 'y' cannot be referenced from a static context
// int b = this.y; // 'A.this' cannot be referenced from a static context
}
}
静态语句块
静态语句块在类初始化时运行一次。
public class A {
static {
System.out.println("123");
}
public static void main(String[] args) {
A a1 = new A();
A a2 = new A();
}
}
结果 :123
静态内部类
非静态内部类依赖于外部类的实例,也就是说需要先创建外部类实例,才能用这个实例去创建非静态内部类。而静态内部类不需要。
public class OuterClass {
class InnerClass {
}
static class StaticInnerClass {
}
public static void main(String[] args) {
// InnerClass innerClass = new InnerClass(); // 'OuterClass.this' cannot be referenced from a static context
OuterClass outerClass = new OuterClass();
InnerClass innerClass = outerClass.new InnerClass();
StaticInnerClass staticInnerClass = new StaticInnerClass();
}
}
静态内部类不能访问外部类的非静态的变量和方法。
静态导包
在使用静态变量和方法时不用再指明 ClassName,从而简化代码,但可读性大大降低。
import static com.xxx.ClassName.*
初始化顺序
静态变量和静态语句块优先于实例变量和普通语句块,静态变量和静态语句块的初始化顺序取决于它们在代码中的顺序。
public static String staticField = "静态变量";
static {
System.out.println("静态语句块");
}
public String field = "实例变量";
{
System.out.println("普通语句块");
}
最后才是构造函数的初始化。
public InitialOrderTest() {
System.out.println("构造函数");
}
存在继承的情况下,初始化顺序为:
父类(静态变量、静态语句块)
子类(静态变量、静态语句块)
父类(实例变量、普通语句块)
父类(构造函数)
子类(实例变量、普通语句块)
子类(构造函数)
final 修饰符
final 变量:
final 表示"最后的、最终的"含义,变量一旦赋值后,不能被重新赋值。被 final 修饰的实例变量必须显式指定初始值。声明数据为常量,可以是编译时常量,也可以是在运行时被初始化后不能被改变的常量。
final 修饰符通常和 static 修饰符一起使用来创建类常量。
对于基本类型,final 使数值不变;
对于引用类型,final 使引用不变,也就不能引用其它对象,但是被引用的对象本身是可以修改的。
public class Test{
final int value = 10; // 下面是声明常量的实例
public static final int BOXWIDTH = 6;
static final String TITLE = "Manager";
public void changeValue(){
value = 12; //将输出一个错误
}
final A y = new A();
}
final 方法
类中的 final 方法可以被子类继承,但是不能被子类修改。声明 final 方法的主要目的是防止该方法的内容被修改。
如下所示,使用 final 修饰符声明方法。
public class Test{ public final void changeName(){ // 方法体 } }
final 类
final 类不能被继承,没有类能够继承 final 类的任何特性。声明方法不能被子类重写。private 方法隐式地被指定为 final,如果在子类中定义的方法和基类中的一个 private 方法签名相同,此时子类的方法不是重写基类方法,而是在子类中定义了一个新的方法。
public final class Test { // 类体 }
abstract 修饰符
抽象类:
抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。
一个类不能同时被 abstract 和 final 修饰。如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误。
抽象类可以包含抽象方法和非抽象方法。
abstract class Caravan{
private double price;
private String model;
private String year;
public abstract void goFast(); //抽象方法
public abstract void changeColor();
}
抽象方法
抽象方法是一种没有任何实现的方法,该方法的的具体实现由子类提供。抽象方法不能被声明成 final 和 static。任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类可以不包含抽象方法。抽象方法的声明以分号结尾,例如:public abstract sample();。
public abstract class SuperClass{
//抽象方法
abstract void m();
}
class SubClass extends SuperClass{
//实现抽象方法
void m(){
.........
}
}
synchronized 修饰符
synchronized 关键字声明的方法同一时间只能被一个线程访问。synchronized 修饰符可以应用于四个访问修饰符。
public synchronized void showDetails(){ ....... }
transient 修饰符
序列化的对象包含被 transient 修饰的实例变量时,java 虚拟机(JVM)跳过该特定的变量。
该修饰符包含在定义变量的语句中,用来预处理类和变量的数据类型。
public transient int limit = 55; // 不会持久化
public int b; // 持久化
volatile 修饰符
volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
一个 volatile 对象引用可能是 null。
public class MyRunnable implements Runnable {
private volatile boolean active;
public void run() {
active = true;
// 第一行
while (active) {
// 代码
}
}
public void stop() {
active = false; // 第二行
}
}
通常情况下,在一个线程调用 run() 方法(在 Runnable 开启的线程),在另一个线程调用 stop() 方法。 如果 第一行 中缓冲区的 active 值被使用,那么在 第二行 的 active 值为 false 时循环不会停止。
但是以上代码中我们使用了 volatile 修饰 active,所以该循环会停止。