Java import 包(package)

解决问题:随着程序不断扩展,程序中就会出现同名称类。当使用有多个一样名称类时,就会出现冲突。程序不知道到底使用哪一个具体类!
解决方案:Java 引入了包(package)机制,提供了类的多层命名空间,用于解决类的命名冲突、类文件管理等问题。避免了名称上的冲突。
使用包优点:

  1. 1. 区分相同名称的类。
  2. 1. 能够较好地管理大量的类。
  3. 1. 控制访问范围。

包定义

ava 中使用 package 语句定义包,package 语句应该放在源文件的第一行,在每个源文件中只能有一个包定义语句,并且 package 语句适用于所有类型(类、接口、枚举和注释)的文件。定义包语法格式如下:package 包名;
Java 包的命名规则如下:

  1. - 包名全部由小写字母(多个单词也全部小写)。
  2. - 如果包名包含多个层次,每个层次用“.”分割。
  3. - 包名一般由倒置的域名开头,比如 com.baidu,不要有 www
  4. - 自定义包不能 java 开头。

注意:如果在源文件中没有定义包,那么类、接口、枚举和注释类型文件将会被放进一个无名的包中,也称为默认包。在实际企业开发中,通常不会把类定义在默认包下。

包导入

不导包写法:example.Test test = new example.Test();
导包后写法:Test test = new Test();
导包主要为简化编程代码。上述代码导包示例:import example.Test;
导指定包下全部类:import example.*;
Java 默认为所有源文件导入 java.lang 包下的所有类,因此前面在 Java 程序中使用 String、System 类时都无须使用 import 语句来导入这些类。
在极端情况下:在同一类中使用不同包下的同名类,怎么办呢?

系统包

说明
java.lang Java 的核心类库,包含运行 Java 程序必不可少的系统类,如基本数据类型、基本数学函数、字符串处理、异常处理和线程类等,系统默认加载这个包
java.io Java 语言的标准输入/输出类库,如基本输入/输出流、文件输入/输出、过滤输入/输出流等
java.util 包含如处理时间的 Date 类,处理动态数组的 Vector 类,以及 Stack 和 HashTable 类
java.awt 构建图形用户界面(GUI)的类库,低级绘图操作 Graphics 类、图形界面组件和布局管理
(如 Checkbox 类、Container 类、LayoutManger 接口等),以及用户界面交互控制和事
件响应(如 Event 类)
java.awt.image 处理和操纵来自网上的图片的 Java 工具类库
java.wat.peer 很少在程序中直接用到,使得同一个 Java 程序在不同的软硬件平台上运行
java.net 实现网络功能的类库有 Socket 类、ServerSocket 类
java.lang.reflect 提供用于反射对象的工具
java.util.zip 实现文件压缩功能
java.awt.datatransfer 处理数据传输的工具类,包括剪贴板、字符串发送器等
java.sql 实现 JDBC 的类库
java.rmi 提供远程连接与载入的支持
java. security 提供安全性方面的有关支持

Java import static静态导入

JDK 1.5 之后增加了一种静态导入的语法;用于导入指定类的某个静态成员变量、方法或全部的静态成员变量、方法。如果一个类中的方法全部是使用 static 声明的静态方法,则在导入时就可以直接使用 import static 的方式导入。
import 和 import static 的作用,使用 import 可以省略写包名,而使用 import static 可以省略类名。

  1. //格式:
  2. import static package.ClassName.fieldName|methodName;
  3. //静态导入Math类下的全部方法、字段
  4. import static java.lang.Math.*;
  5. //静态导入Math类下的sqrt方法
  6. import static java.lang.Math.sqrt;

Java构造方法

构造方法是类的一种特殊方法,用来初始化类的一个新的对象,在创建对象(new 运算符)之后自动调用。Java 中的每个类都有一个默认的构造方法,如果类中显式地定义了一个或多个构造方法,则 Java 不再提供默认构造方法。并且可以有一个以上的构造方法。
构造方法必须满足要求:

  1. 1. 方法名必须与类名相同;
  2. 1. 可以有 0 个、1 个或多个参数;
  3. 1. 没有任何返回值,包括 void
  4. 1. 默认返回类型就是对象类型本身;
  5. 1. 只能与 new 运算符结合使用;

注意:
1 . this()调用构造函数时必须放在构造函数的第一行代码位置!!!!
2 . 如果为构造方法定义了返回值类型或使用 void 声明构造方法没有返回值,编译时不会出错,但 Java 会把这个所谓的构造方法当成普通方法来处理。
3 . 构造方法不能被 static、final、synchronized、abstract 和 native(类似于 abstract)修饰。构造方法用于初始化一个新对象,所以用 static 修饰没有意义。构造方法不能被子类继承,用 final 和 abstract 修饰没有意义。多个线程不会同时创建内存地址相同的同一个对象,所以用 synchronized 修饰没有必要。
构造方法不是没有返回值吗?为什么不能用 void 声明呢?
这是 Java 的语法规定。实际上,类的构造方法是有返回值的,当使用 new 关键字来调用构造方法时,构造方法返回该类的实例,可以把这个类的实例当成构造器的返回值,因此构造器的返回值类型总是当前类,无须定义返回值类型。但必须注意不要在构造方法里使用 return 来返回当前类的对象,因为构造方法的返回值是隐式的。

  1. public class Gamer {
  2. public String name; // 姓名
  3. private int age; // 年龄
  4. // 定义带有一个参数的构造方法
  5. public Gamer(String name) {
  6. this.name = name;
  7. }
  8. // 定义带有两个参数的构造方法
  9. public Gamer(String name,int age) {
  10. this.name = name;
  11. this.age = age;
  12. }
  13. public String toString() {
  14. return "我是玩家,我叫"+name+",今年"+age+"岁。";
  15. }
  16. }

Java析构方法

析构方法与构造方法相反,当对象脱离其作用域时(例如对象所在的方法已调用完毕),系统自动执行析构方法。析构方法往往用来做清理垃圾碎片的工作,例如在建立对象时用 new 开辟了一片内存空间,应退出前在析构方法中将其释放。
在 Java 的 Object 类中还提供了一个 protected 类型的 finalize() 方法,因此任何 Java 类都可以覆盖这个方法,在这个方法中进行释放对象所占有的相关资源的操作。
对象的 finalize() 方法具有如下特点:

  • 垃圾回收器是否会执行该方法以及何时执行该方法,都是不确定的。
  • finalize() 方法有可能使用对象复活,使对象恢复到可触及状态。
  • 垃圾回收器在执行 finalize() 方法时,如果出现异常,垃圾回收器不会报告异常,程序继续正常运行。

由于 finalize() 方法的不确定性,所以在程序中可以调用 System.gc() 或者 Runtime.gc() 方法提示垃圾回收器尽快执行垃圾回收操作。

  1. public class Counter {
  2. private static int count = 0; // 计数器变量
  3. public Counter() {
  4. // 构造方法
  5. this.count++; // 创建实例时增加值
  6. }
  7. public int getCount() {
  8. // 获取计数器的值
  9. return this.count;
  10. }
  11. protected void finalize() {
  12. // 析构方法
  13. this.count--; // 实例销毁时减少值
  14. System.out.println("对象销毁");
  15. }
  16. public static void main(String[] args) {
  17. Counter cnt1 = new Counter(); // 建立第一个实例
  18. System.out.println("数量:"+cnt1.getCount()); // 输出1
  19. Counter cnt2 = new Counter(); // 建立第二个实例
  20. System.out.println("数量:"+cnt2.getCount()); // 输出2
  21. cnt2 = null; // 销毁实例2
  22. try {
  23. System.gc(); // 清理内存
  24. Thread.currentThread().sleep(1000); // 延时1000毫秒
  25. System.out.println("数量:"+cnt1.getCount()); // 输出1
  26. } catch(InterruptedException e) {
  27. e.printStackTrace();
  28. }
  29. }
  30. }

Java创建与销毁

创建对象

JAVA的内存图理解(栈,堆,方法区)

显式创建对象
  1. 1. 使用 new 关键字创建对象;格式:类名 对象名 = new 类名();
  2. 1. 调用 java.lang.Class 或者[ java.lang.reflect.Constuctor ](https://segmentfault.com/a/1190000016511589)类的 newlnstance() 实例方法
  1. //示例
  2. Class<?> 类对象名称 = java.lang.Class.forName(要实例化的类全称);
  3. 类名 对象名 = (类名)Class类对象名称.newInstance();
  4. Class<?> aClass = Class.forName("java.lang.String");//exception: java.lang.ClassNotFoundException
  5. Object str = aClass.newInstance();//Exception, java.lang.IllegalAccessException
  1. 3. 调用对象的 clone() 方法;该方法不常用,使用该方法创建对象时,要实例化的类必须继承 java.lang.Cloneable 接口。调用对象的 clone() 方法创建对象。格式:类名 对象名 = (类名)已创建好的类对象名.clone();
  2. 3. 调用 java.io.ObjectlnputStream 对象的 readObject() 方法

注意事项:

  1. - 使用 new 关键字或 Class 对象的 newInstance() 方法创建对象时,都会调用类的构造方法。
  2. - 使用 Class 类的 newInstance() 方法创建对象时,会调用类的默认构造方法,即无参构造方法。
  3. - 使用 Object 类的 clone() 方法创建对象时,不会调用类的构造方法,它会创建一个复制的对象,这个对象和原来的对象具有不同的内存地址,但它们的属性值相同。
  4. - 如果类没有实现 Cloneable 接口,则 clone。方法会抛出 java.lang.CloneNotSupportedException 异常,所以应该让类实现 Cloneable 接口。

隐含创建对象
  1. 1. String strName = "strValue",其中的“strValue”就是一个 String 对象,由 Java 虚拟机隐含地创建。
  2. 1. Java 虚拟机加载一个类时,会隐含地创建描述这个类的 Class 实例。

提示:类的加载是指把类的 .class 文件中的二进制数据读入内存中,把它存放在运行时数据区的方法区内,然后在堆区创建一个 java.lang.Class 对象,用来封装类在方法区内的数据结构。
无论釆用哪种方式创建对象,Java 虚拟机在创建一个对象时都包含以下步骤:

  • 给对象分配内存。
  • 将对象的实例变量自动初始化为其变量类型的默认值。
  • 初始化对象,给实例变量赋予正确的初始值。

注意:每个对象都是相互独立的,在内存中占有独立的内存地址,并且每个对象都具有自己的生命周期,当一个对象的生命周期结束时,对象就变成了垃圾,由 Java 虚拟机自带的垃圾回收机制处理。

销毁对象

在清除对象时,由系统自动进行内存回收,不需要用户额外处理。
Java 语言的内存自动回收称为垃圾回收(Garbage Collection)机制,简称 GC。垃圾回收机制是指 JVM 用于释放那些不再使用的对象所占用的内存。
Java 语言并不要求 JVM 有 GC,也没有规定 GC 如何工作。不过常用的 JVM 都有 GC,而且大多数 GC 都使用类似的算法管理内存和执行回收操作。具体的垃圾回收实现策略有很多种。如:标记 - 清除算法|整理算法、复制算法、分代算法等到。
注意:调用 System.gc() 或者 Runtime.gc() 方法也不能保证回收操作一定执行,它只是提高了 Java 垃圾回收器尽快回收垃圾的可能性。
在 Java 虚拟机的堆区,每个对象都可能处于以下三种状态之一。
1)可触及状态:当一个对象被创建后,只要程序中还有引用变量引用它,那么它就始终处于可触及状态。
2)可复活状态:当程序不再有任何引用变量引用该对象时,该对象就进入可复活状态。在这个状态下,垃圾回收器会准备释放它所占用的内存,在释放之前,会调用它及其他处于可复活状态的对象的 finalize() 方法,这些 finalize() 方法有可能使该对象重新转到可触及状态。
3)不可触及状态:当 Java 虚拟机执行完所有可复活对象的 finalize() 方法后,如果这些方法都没有使该对象转到可触及状态,垃圾回收器才会真正回收它占用的内存。

  1. {
  2. // 第一种情况:对象o的作用范围,超过这个范围对象将被视为垃圾
  3. Object o = new Object();
  4. // 第二种情况:对象被赋值为null将被视为垃圾
  5. o = null;
  6. }