包:对类文件进行分类管理。
给类提供多层命名空间。
写在程序文件的第一行。
类名的全称的是:包名.类名。
包也是一种封装形式。
示例1:
1. package mypack;//包,package是首字母小写。
2.
3. class PackageDemo{
4. publicstatic void main(String[] args){
5. System.out.println("Hello Package!");
6. }
7. }
8.
复制代码
运行结果:编译通过。运行报错。 没有找到这样的类
创建mypack文件夹,并且将PackageDemo.class放入其中,然后再次执行。
直接java mypack.PackageDemo
运行结果:
也可以通过javac命令直接创建mypack文件夹,然后执行。
示例2:
DemoA.java
1. package packa;
2.
3. public class DemoA{
4. publicvoid show(){
5. System.out.println("demoa show run");
6. }
7. }
8.
复制代码
PackageDemo.java
1. package mypack;
2.
3. class PackageDemo{
4. publicstatic void main(String[] args){
5. //新创建一个对象packa.DemoA
6. packa.DemoA d = new packa.DemoA();
7. d.show();
8. System.out.println("Hello Package!");
9. }
10. }
11.
复制代码
Cmd命令行输入javac –d. DemoA.java创建生成DemoA.class文件。
运行结果:
P.S.
包与包之间的类进行访问,被访问的包中的类必须是public的,被访问的包中的类的方法也必须是public的。
示例3:
DemoA.java
1. package packa;
2.
3. public class DemoA extends packb.DemoB{//A继承B
4. publicvoid show(){
5. method();
6. System.out.println("demoa show run");
7. }
8. }
复制代码
DemoB.java
1. package packb;
2. public class DemoB{
3. //protected修饰的用法???如果method的方法属于子类覆盖。和它的父类不在同一个包中。
4. protected void method(){
5. System.out.println("demob show run" );
6. }
7. }
8.
复制代码
PackageDemo.java
1. package mypack;
2.
3. class PackageDemo{
4. publicstatic void main(String[] args){
5. packa.DemoA d = new packa.DemoA();
6. d.show();//调用A中的show
7.
8. packb.DemoB b = new packb.DemoB();
9. //b中的method方法,既不在该包,又不存在子类关系。
10. //b.method();//报错!无法访问DemoB中的protected修饰的method方法对同包中的类是可见的
11. System.out.println("Hello Package!");
12. }
13. }
14.
复制代码
运行结果:
包之间的访问:被访问的包中的类权限必须是public的。
类中的成员权限:public或者protected。
protected是为其他包中的子类提供的一种权限。
四种权限
import
一个程序文件中只有一个package,但可以有多个import。
示例:
DemoA.java
1. package packa;
2.
3. public class DemoA extends packb.DemoB{//A继承B
4. public void show(){
5. method();
6. System.out.println("demoa show run");
7. }
8. }
复制代码
DemoB.java B是父类。
1. package packb;
2. public class DemoB{
3. protected voidmethod(){//用protected提供了对子类的访问
4. System. out.println("demob show run" );
5. }
6. }
复制代码
PackageDemo.java
1. package mypack;
2. //import packa.DemoA;//导入了 packa包中的DemoA类。
3. import packa.*; //导入了packa包中所有的类。*代表所有;
4. //导入A
5. class PackageDemo{
6. publicstatic void main(String[] args){
7. DemoA d = new DemoA();//为什么先,打印B???
8. 一、method访问其它类中有protected的method
9. 二、protected能被该类的子类所访问,子类可以和父类不在一个包中。
10. //A已经导入进同一个包,可以调用
11. d.show();
12. }
13. }
14.
复制代码
运行结果:
示例:
有两个类:DemoA、DemoAbc。
所在文件目录如下:
packa\DemoA.class
packa\abc\DemoAbc.class
导包语句如下:
import packa.*;
import packa.abc.*;
Jar包: Java的压缩包。
方便项目的携带。
方便于使用,只要在classpath设置jar路径即可。
数据库驱动,SSH框架等都是以jar包体现的。
Jar包的操作:
通过jar.exe工具对jar的操作。
创建jar包:
jar -cvf mypack.jar packa packb
查看jar包
jar -tvf mypack.jar [>定向文件]
解压缩
jar -xvf mypack.jar
自定义jar包的清单文件
jar–cvfm mypack.jar mf.txt packa packb
5、多线程
5.1.1 进程、线程、多进程的概念
进程:正在进行中的程序(直译)。
线程:进程(正在进行的程序)中一个负责程序执行的控制单元(执行路径)。
P.S.
1、一个进程中可以有多个执行路径,称之为多线程。
2、一个进程中至少要有一个线程。
3、开启多个线程是为了同时运行多部分代码,每一个线程都有自己运行的内容,这个内容可以称为线程要执行的任务。
多线程的好处:解决了多部分代码同时运行的问题。
多线程的弊端:线程太多,会导致效率的降低。
其实,多个应用程序同时执行都是CPU在做着快速的切换完成的。这个切换是随机的。CPU的切换是需要花费时间的,从而导致了效率的降低。
JVM启动时启动了多条线程,至少有两个线程可以分析的出来:
1. 执行main函数的线程,该线程的任务代码都定义在main函数中。
2. 负责垃圾回收的线程。
示例:
1. class Demo extends Object{//继承对象的祖宗
2. public void finalize(){
3. System.out.println("demook");
4. }
5. }
6.
7. class ThreadDemo{
8. public static void main(String[] args){
9. new Demo();
10. new Demo();
11. System.gc();//垃圾回收线程
12. //呼叫java虚拟机的垃圾回收器运行回收内存的垃圾
13. new Demo();
14. System.out.println("HelloWorld!");
15. }
16. }
17.
复制代码
运行结果:
像这种情况,之所以先打印Hello World!再打印demo ok,是因为两条线程是分别执行的。
像这种情况,只打印一个demook,是因为在垃圾回收器还没回收第二个Demo对象的时候,JVM就已经结束了。说明垃圾回收不一定马上执行。
P.S.
System类的gc方法告诉垃圾回收器调用finalize方法,但不一定立即执行。
5.1.2 创建线程方式一:继承Thread类
1. 定义一个类继承Thread类。
2. 覆盖Thread类中的run方法。
3. 直接创建Thread的子类对象创建线程。
4. 调用start方法开启线程并调用线程的任务run方法执行。
单线程程序示例:
1. class Demo{
2. private String name ;
3. Demo(String name){//构造函数
4. this.name = name;
5. }
6. public void show(){
7. for(int x = 0; x < 10; x++){
8. System.out.println(name + "...x=" + x);
9. }
10. }
11. }
12.
13. class ThreadDemo{
14. public static void main(String[] args){
15. Demo d1 = new Demo("旺财");//name=旺财
16. Demo d2 = new Demo("小强");
17. d1.show();
18. d2.show();
19. }
20. }
21.
复制代码
运行结果:
可以看到在单线程程序中,只有上一句代码执行完,下一句代码才有执行的机会。
创建线程的目的就是为了开启一条执行路径,去运行指定的代码和其他代码实现同时运行,而运行的指定代码就是这个执行路径的任务。
jvm创建的主线程的任务都定义在了主函数中。
而自定义的线程,它的任务在哪儿呢?
Thread类用于描述线程,线程是需要任务的。所以Thread类也有对任务的描述。
线程的任务就是通过Thread类中的run方法来体现。
也就是说,run方法就是封装自定义线程运行任务的函数,run方法中定义的就是线程要运行的任务代码。
开启线程是为了运行指定代码,所以只有继承Thread类,并复写run方法,将运行的代码定义在run方法中即可。
多线程程序示例:
1. class Demo extends Thread{//1,继承Thread类
2. private String name ;
3. Demo(String name){
4. this.name = name;
5. }
6. publicvoid run(){//2,复写run方法
7. for(int x = 0; x < 10; x++){
8. System.out.println(name +"...x=" + x + "...ThreadName=" +Thread.currentThread ().getName());
9. }
10. }
11. }
12.
13. class ThreadDemo{
14. publicstatic void main(String[] args){
15. Demo d1 = new Demo("旺财");
16. Demo d2 = new Demo("xiaoqiang");
17. d1.start(); //开启线程,调用run方法。
18. d2.start();
19. for(int x = 0; x < 20; x++){
20. System.out.println("x =" + x + "...over..." +Thread.currentThread().getName());
21. }
22. }
23. }
24.
复制代码
运行结果:
P.S.
1、可以通过Thread的getName方法获取线程的名称,名称格式:Thread-编号(从0开始)。
2、Thread在创建的时候,该Thread就已经命名了。源码如下: