JAVA从入门到实战

本文是一篇关于Java SE的自学笔记,涵盖了从Java简介、数据类型、流程控制语句到面向对象、异常处理、多线程编程等多个章节。详细介绍了Java的特性,如跨平台性、安全性,并讨论了JVM的运行原理。还涉及了数据类型的运算符、数组、方法、面向对象概念、异常处理、工具类、集合、文件与流、多线程以及网络编程基础。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

# JAVA SE
前言:本文是我的自学Java笔记,仅记录回顾所用,还未完善勿喷,图片未添加。文章是2020年写的,忘记发了,如有不对的地方请各位师傅指出,感谢!!!(尽快完善尽快完善)

事事难上难,举足常虞失坠。件件想一想,浑身都是过差。——清·金缨

第一章-java的简介

1、java是什么?

一种编程语言
高级编程语言:c/c++,java,php,javaScript,python…
因为计算机只能认识二进数,不能识别高级语言,所以所有的高级语言都需要转变为机器语言

  • 高级编程语言分为二种:
    • 编译型语言(c/c++):

      • 需要先将源代码进行编译,转换为特定的可执行文件(平台能直接执行的二进制文件)
      • 优点:编译一次,永久执行,当你发布可执行文件给客户时不需要提供源代码, 只需要提供一个可执行的二进制文件即可,体现了安全性、执行速度快
      • 缺点:不能跨平台
    • 解释型语言(javaScript,python):

      • 需要一个解释器,在源代码执行的时候被解释器翻译为一个与平台无关的中间代码,之后再翻译成各平台的机器语言
      • 特点:夸平台
      • 缺点:运行时需要源代码,运行速度慢

2、java的发展历程

开始研究 1990
Oak 1991.6
HotJava 1995.5
Java1.0 1995.5.23
Java1.1 1997.2.18
Java 1.2 1998.12.4
Java1.3 2000.5.8
Java1.4 2002.2.13
Java5.0 2004.9
Java6.0 2006.4
Oracle74亿美元收购sun 2009.4.20
Java7 2011.7.28
Java8 2014.3.19
Java9 2017.9.21

3、java的特征

  1. java的特征
    • 半编译半解释
    • java会将代码编译成一个.class文件(不完全编译),再将.class文件解释称各平台能够识别的机器语言
    • 跨平台
    • 速度快
    • 安全
    • 健壮
    • 分布式:垂直分布式、水平分布式
    • 多线程
  2. [面试题]jvm是什么?jvm的运行原理?jvm的生命周期
    • jvm:java虚拟机(相当于一个翻译官)
    • 运行原理:java编译器先将代码编译成.class,java虚拟机再将.class文件解释成各个平台能够识别的机器语言,每个平台都有自己的jvm因为有不同系统版本的jdk。
    • 生命周期:当遇到main时候jvm开始运行,main方法运行完成的时候jvm结束;如果说有10个main同时执行,10java虚拟机在运行,他们互不影响。

4、java语言的版本

 javaSE(java核心技术)、javaEE(java企业级开发技术,javaWEB)、javaME(小型版本)

5、安装JDK

  • 无论使用什么样的编程语言开发,都要安装SDK,在java中称为JDK。JDK:JAVA开发工具包。JRE:JAVA运行环境

  • [面试题] JRE和JVM的关系?

    答:JRE=JVM+基本的数据包+JAVA依赖包

  • JDK目录结构:bin:存放可执行文件 java.exe javac.exe,lib:存放一些二进制文件和所依赖的包

6、关键字,保留字,标识符

关键字:java中特殊的英文单词,内部编译器自动识别
保留字:暂定为java使用,还没有真正成为关键字,以后用不用还不确定
标识符:包、类、方法、参数和变量的名称总称为标识符

  • 命名规则:
    规则:
    必须以字母、下划线(_)或美元符号($)开头;
    余下的字符可以是下划线、美元符号或任何的字母或数字,长度不限;
    标识符中不能有空格;
    不能使用Java中的关键字或者保留字做为标识符;

  • 规范:
    1、包:域名.公司名.项目名.种族 com.nesoft.java150219.test
    2、类名:驼峰命名法 /_/_/\ 首字母一定要大写Student , HelloWorld ,Hello_world
    3、方法名:驼峰命名法 /_/_/\ 首字母一般要小写 getName(),get(), set_sex()
    4、参数和变量名:驼峰命名法 /_/_/\ 首字母一般要小写 int maxAge
    5、常量名全部大写

7、String[] args java虚拟机默认传入的字符数组参数

第二章-数据类型

1、基本数据类型

数值型:
byte, short, int, long     一个字节8位   1G=1024m 1m=1024k 1k=1024b
byte 1字节8位   -2^7-2^7-1  ,即-127到128
short 2字节16 -2^15-2^15-1
int 4字节32位  -2^31-2^31-1  java中默认的整型
long 8字节64位 -2^63-2^63-1
long b4=12312312;  //发生了隐式转换 12312312是int类型,自动转换long
long b5=12312312L;  //一般声明Long类型数据时,在数据的后面加上L
Java中不同进制整型的表示形式
十进制 第一位不是0   例:10等
十六进制A:10 F:15     例:0xF     运算5*16^0+4*16^1=690x45
八进制   例:0125     运算:5*8^0+2*8^1+1*8^2  第一位是0
二进制 必须以ob开头  例:0b10101001                         
浮点型: double,float
double: 8字节 64位  -2^63-2^63-1     java中默认的浮点型
float: 4字节 32位  -2^31-2^31-1    float和long一样需要在变量值后加首字母
字符型:char
char 是字符时只能表示单个字符
char c2=49;  //是整数时,是一个16位无符号整数 ,jvm会找到acsii表找到整数对应acsii值

转义字符:   \    ,\n代表的是回车(换行)
             System.out.println("你好,\"中国\"");
布尔型: boolean -->false=0 true=1 一般用于判断比较

2、变量

变量 :临时存放数据的场所
局部变量:在方法中或则代码块中声明的变量,一定是初始化之后变量才能使用

数据类型的相互转换
   byte:1个字节 8位 -128~127
   short :2个字节 16位 (-2^15~2^15-1)
   int :4个字节 32位 (-2^31~2^31-1)
   long:8个字节 64位 (-2^63~2^63-1)
   浮点型:
   float:4个字节 32 位
   double :8个字节 64位
   注:默认的是double类型,如3.14是double类型的,加后缀F(3.14F)则为float类型的。
   char类型:
   char:2个字节。
   Boolean 类型:
   boolean: (true or false)(并未指明是多少字节  1字节  1位 4字节)

   1.隐式转换:就是把小精度的数值直接赋值给大精度数据类型,会发生隐式转换    
   		例:  short a1=10; int a2=a1;
   2.显示转换:就是需要使用强制转换,当大精度的类型的数值要变小精度的类型数值时需要实现强制转换;
   		但可能会导致精度缺失,发生后果自负 例:int a=10;short b=(short)a;
  3.byte、short、char之间不会相互转换,他们三者在计算时首先会转换为int类型
  4.int接收的是一个字符,jvm会去找acsii表,char接收的是一个整型是,jvm会去找acsii表

3、赋值运算符

赋值运算符: + - * /  %(求余)
1.赋值的时候从右往左计算,例将20赋给a int a=20;
2.a=a+10,可以写成a+=10; 加减乘除同理

4、算术运算符

1.++a先自增1,后运算
2.a++先运算后,后自增1

5、比较运算符

  比较运算符>、<、>=、 <=、= =、!=、instanceof
    1.比较运算符,返回boolean, if(){}的条件返回的也是boolean    
    		boolean temp=1>2;    
    		boolean t1=1!=2;
    2.==用于数值类型比较  比较就是两个数值是否相同
    		boolean t2=1==2;
    3.//instanceof 比较是否是同一个对象 用于引用类型数据
        Date d=new Date();
        Date d1=new Date();
        boolean t3=d instanceof Date;
        if(d instanceof Date) {
             System.out.println("d是日期类型,可以转为字符串类");
        }

6、逻辑运算符

 &&逻辑与,||逻辑或(),逻辑非 !
  1.&&逻辑与 表达式两边都为true才为true  表达式一&&表达式二
  2.逻辑或 || 达式一边都为true就为true  表达式一||表达式二
  3.逻辑非  对结果取反
     if(!false) {
            System.out.println("true");
       }

7、按位运算符

按位运算符byte short char int long有效
按位运算符:     &      |     ^     ~    >>     <<      >>>
1. & 按位与 & 只有参加运算的两位都为1,&运算的结果才为1,否则为0
       int i=5&2;
    /*   0101 ---5
         0010 ---2
         0000 ---0*/
2. | 按位或 | 只有参加运算的两位都为0,|运算的结果才为0,否则为1
       int j=29|5;
    /*011101  --29
      000101 --5
      011101 --29*/
3. ^ 异或 只有参加运算的两位不同,^运算的结果才为1,否则为0
       int h=29^5;
    /*0001 1101  --29
      0000 0101   --5
      0001 1000--24*/
4. << 左移 << n<<m n*2^m   符号位:0代表正数  1代表负数
       int k=5<<2;
    /*0000 0101
      0001 0100*/
5. >> 右移 >>  
       int g=5>>2;
    /*0000 0101
      0000 0001*/
6. >>>  >>>:无符号右移。无论是正数还是负数,高位通通补0

7.左移的正负数,右移是正数,都可以套用公式  n>>m n/2^m
8.注意:负数的左移右移,将原码转为补码再移动,最后将得到的结果转为原码。
	反码时原码取反, 补码是反码+1;
   	int num=-9<<2;
    /*1000 1001 --原码
     *1111 0110 --反码
     *1111 0111 --补码
     *
     *1111 011100 --左移结果
     *1111 011011 补码反反码
     *1000 100100 //36   原码
     */
9.正数右移左边空余部分补0  负数右移左边空余部分补1
    int num2=-9>>2;
    /*1000 1001 --原码
     *1111 0110 --反码
     *1111 0111 --补码
     *
     *1111 1101 --右移结果
     *1111 1100 补码转反码
     *1000 0011  //-3   原码
     */

8、按位运算和逻辑运算的区别

1.表达式一&&表达式二  ,表达式一&表达式二
2.按位与& 逻辑与&&的区别:
	&&具有短路功能,若果表达式一为false,不执行表达式二   
	&不具有短路功能 表达式一和表达式二无论如何都执行
3.表达式一||表达式二  ,表达式一|表达式二
4.按位或| 逻辑或||的区别:   
	||具有短路功能,若果表达式一为true,不执行表达式二   
	|不具有短路功能 表达式一和表达式二无论如何都执行

9、三元运算符

三元表达式:表达式1?表达式2:表达式3; 
	表达式1的结果为true时,就为第二个表达式,如果为false时,就为第三个表达式
技巧:从右往左计算
例如:boolean t1=false?true:false?false:false?true:false?true:false;结果为false

10、String类

String类: 引用类型(对象类型)和基本数据类型的区别
         只要是变量的声明都放在栈区
         基本数据类型数据存在栈区
         引用类型数据类型存在堆区
new 内存空间分配符(在堆中)
1.声明变量初始化的时候就已经是在内存中创建了一个对象
2.==用于引用数据类型比较的时候,比较的时两个对象的地址
3.但内存中有对象了,就不会重新创建,例内存中已经有zhangsan了,如果再想创建String s4=new String("zhangsan"); //这样声明在内存中创了多少个对象 1个
4.若没有,String s4=new String("lisi"); //这样声明在内存中创了多少个对象 2个
5.System.out.println("y"+y); //任何数据类型和字符串拼接都会变成字符串

第三章-流程控制语句

1、if语句

if语句 :表达式为true那么执行if语句体;if(表达式){}
(1).单分支 if(表达式){}
(2).多分支
   if(表达式){
       }else if(){
           }else{}

2、Switch语句

(1).switch (表达式){
   case 取值1:
   语句块1                      
   …
   case 取值n:
   语句块n                      
   default:          
   语句块n+1  
   }
(2).case的取值一定要和switch中的表达式的数据类型一致,case值必须是常量,不能跟变量。
(3).break:跳出switch语句
(4).switch语句的结束:
	遇到break语句或者如果满足条件执行语句块,但是没有遇到break语句会继续往下执行直到遇到下一个break语句为止,如果没有break语句一直执行到switch语句的最后

3、for循环

  (1).for(初始化表达式;循环条件表达式;循环后的操作表达式){
               执行语句块
        }
  (2).死循环产生的条件:没有循环终止条件
  (3).注意:死循环之后的代码都不能通过编译
   死循环有:
   for(;;){死循环1};
   for(int i=0;;){死循环2};
   for(int i=-1;i<=0;){死循环3};
   for(int i=0;;i++){死循环4}

4、while和do…while

  where(表达式){  表达式做条件判断--boolean  }
  do{}while() 无论如何都会执行一次语句块
  (1).while的死循环
       while(true) {死循环1};while(i<100) {死循环2};

5、变量的作用域

  (1).变量的作用域:变量要初始化之后才能使用;
       在同一个作用域范围内,变量不能重新被定义;
  (2).若变量在main方法声明,则在if或者其它语句中,不可重复声明;
       若变量在if或者其它语句中声明,则只能在其语句中可使用,离开此语句不能使用;

6、控制台输入和随机数

  (1).控制台输入:Scanner sc=new Scanner(System.in);//需要scanner包
       sc.next();//读取一个字符串,以空格结束
       sc.nextInt();//读取整数
       sc.Double();//浮点型
       sc.nextLine();// 读取控制台输入的一整行字符串数据
  (2).随机数:Randow r=new Random();
       r.nextInt(10)//表示随机获取0-9的数
       r.nextInt(10)+1//表示1-10的数

7、循环嵌套和循环中断

(1)练习循环嵌套
//  (1)循环嵌套:九九乘法表
 for(int i=1;i<=9;i++) {
   
   //行数
               for(int j=1;j<=i;j++) {
   
   //列数
                      System.out.print(j+"x"+i+"="+j*i+" ");
                }
               System.out.println();
           }
(2)循环中断(break,continue)

① break

for(int i=1;i<=9;i++) {
   
   //行数
               if(i==5){
   
   break;}//跳出整个循环
               for(int j=1;j<=i;j++) {
   
   //列数
                      System.out.print(j+"x"+i+"="+j*i+" ");
                }
               System.out.println();
           }

②continue

for(int i=1;i<=9;i++) {
   
   //行数
               if(i==5){
   
   continue;}//跳出整个循环
               for(int j=1;j<=i;j++) {
   
   //列数
                      System.out.print(j+"x"+i+"="+j*i+" ");
                }
               System.out.println();
           }

③outer

  outer:for(int i=1;i<=9;i++) {
   
   //行数
                   inner:for(int j=1;j<=i;j++) {
   
   //列数
                       if(i==5){
   
   
                           break outer;    
                       }
                          System.out.print(j+"x"+i+"="+j*i+" ");
                    }
                   System.out.println();
               }

二、数组(第四章)

1、数组:int[] arr1= {元素1,元素2…} 就一个容器

(1).特点:声明什么类型的数组就只能存放什么数据类型的数据;
              数组是定长(数组长度不可变);
(2).当声明的数组没有给定值,会有默认的值  
		String(引用数据类型)-->null  char-->' '  int-->0  double-->0.0
(3).int[] arr3=new int[5]; -->初始化时必须指定数组的长度
(4).数组的声明和创建,
     ①int[] arr={1,2};//创建并且初始化
     ②int arr[]={1,2};
     ③int[] arr=new int[5];//创建数组且长度为5;默认值为0;
     ④int[] arr=new in[]{1,2,3}
(5).声明一个int类型的数组  那么只能存放int类型数据
	int[] arr1= {'a',2,3,4,5,5,5,123}; //发生char->int
(6).若给数组单独赋值,则不能超过数组函数长度,超过则出现数组越界异常
(7).通过Arrays类中的toString方法打印输出数组
    	System.out.println(Arrays.toString(arr));

2、数组内存分析

  数组中的数据存放在堆内存,其引用在栈内存
  int[] arr2= {}; //这样声明数组,数组没有长度,没有在对内存中创建数组对象

3、数组的访问

  使用for循环访问数组  数组索引的最大值是数组长度-1(arr.length-1)

4、加强for循环 foreach 一般用于数组对象或者集合的遍历

String[] student={"a","b","c"};
    for(String s:student) {
        System.out.println(s);
    }

5、二维数组

  (1).创建方式①int a[行][列];int[][] b;int[] c [];
  (2).快速访问
  for(int row=0;row<f.length;row++) {
               for(int colum=0;colum<f[row].length;colum++) {
                   System.out.print(f[row][colum]);
               }
               System.out.println();
          }

第四章-数组

1、数组的操作

  • *什么是时间复杂度?
    平方阶 (O(n2)) 排序 各类简单排序:直接插入、直接选择和冒泡排序。
    线性对数阶 (O(nlog2n)) 排序 快速排序、堆排序和归并排序;
    O(n1+§)) 排序,§ 是介于 0 和 1 之间的常数。 希尔排序
    线性阶 (O(n)) 排序 基数排序,此外还有桶、箱排序。

  • 关于稳定性
    稳定的排序算法:冒泡排序、插入排序、归并排序和基数排序。
    不是稳定的排序算法:选择排序、快速排序、希尔排序、堆排序。

  • 名词解释:
    n:数据规模
    k:"桶"的个数
    In-place:占用常数内存,不占用额外内存
    Out-place:占用额外内存

    稳定性:排序后 2 个相等键值的顺序和排序之前它们的顺序相同
    在这里插入图片描述

图片出处:https://www.runoob.com/w3cnote/sort-algorithm-summary.html

(1). 数组拷贝

System.arraycopy(src, srcPos, dest, destPos, length);
src源数组,srcPos开始复 制索引,dest目标数组,destPos开始粘贴索引,长度
System类中的数组拷贝方法对数组进行更新
在这里插入图片描述

(2). 数组的排序

在这里插入图片描述

2、其他算法

(1). 冒泡排序
//arr.length-1和arr.length-j-1的区别,
//arr.length-1就是每一个都要排序,无论是排过序的还要重新对比
//arr.length-j-1,不用重新排已经排好序的数据,提高了排序的效率

在这里插入图片描述

  • 练习:
    在这里插入图片描述
(2). 选择排序
在长度为N的无序数组中,第一次遍历n-1个数,找到最小的数值与第一个元素交换;
第二次遍历n-2个数,找到最小的数值与第二个元素交换;
。。。
第n-1次遍历,找到最小的数值与第n-1个元素交换,排序完成。
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/e9f0e8c47fe04b8484ed641dd9d31bf7.png)
(3). 插入排序
基本思想: 在要排序的一组数中,假定前n-1个数已经排好序,现在将第n个数插到前面的有序数列中,使得这n个数也是排好顺序的。
如此反复循环,直到全部排好顺序。

在这里插入图片描述

(4). 快速排序
基本思想:(分治)
先从数列中取出一个数作为key值;
将比这个数小的数全部放在它的左边,大于或等于它的数全部放在它的右边;
对左右两个小数列重复第二步,直至各区间只有1个数。
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/05b1038e96ed433ca495013623a2de74.png)
(5). 归并排序

基本思想:
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法的一个非常典型的应用。
首先考虑下如何将2个有序数列合并。这个非常简单,只要从比较2个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数。然后再进行比较,如果有数列为空,那直接将另一个数列的数据依次取出即可。 先递归的分解数列,再合并数列
在这里插入图片描述
过程:
在这里插入图片描述

第五章-方法的定义和调用

1、方法的定义和调用

方法的声明:
[访问控制符] [修饰符] 返回值类型 方法名(参数类型 形式参数,参数类型 形式参数,…){
方法体
}

一个方法的结束的标志: 遇到return语句或者方法的结束 一个有返回值的方法只会执行一次return语句

成员变量(属性): [访问修饰符]数据类型 + 名(int age);

无参无返回值: void代表该方法没有返回值

public void getName() {
      System.out.println("getName()");
 }

有参无返回值: int age 是形式参数 --为了告诉开发者需要传入什么类型的参数

public void setName(int age) {
      System.out.println("setName()");
}

无参有返回值: return 有返回值的方法必须有return语句 返回一个和声明方法时定义的返回值类型相同数据类型值

public int getAge() {
//业务逻辑处理后的一个结果返回给调用此方法的方法
              int age=10;
              return age;
       }

注意:方法里面也可以调用其他的方法

public String getAge1() {
       String studentName=null;
        int age=getAge();
        System.out.println(age);
        if(age>5) {
            studentName="wangwu";
        }
       return studentName;
       //return 123; 必须和声明的数据类型一致
   }

有参有返回值:

public boolean setAge(int sex) {        
        boolean s =true;
       System.out.println("我的返回值是boolean");
        return true;
   }

注意:
1)调用有参的方法时,一定要给方法传入实参 --具体的参数 方法需要多少个参数,调用时就需要传多少个参数
2)有返回值的方法被调用后,获得的结果可以用对应的数据类型变量来接收 ,拿到结果后可以对结果进行进一步操作

2、方法的重载

方法的重载:
前提:在同一个类中
一同一不同:方法名相同参数列表不同(参数个数不同或者参数的类型不同);返回值可同可不同;
在这里插入图片描述

3、引用传递和值传递

引用传递:传递的是地址
值传递:传递的是值
在这里插入图片描述

内存图:
在这里插入图片描述

第六章-面向对象基础

1、类的对象

面向对象与面向过程的区别:
面向过程:就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了
面向对象:是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为

类的定义、属性、方法
类的定义:把相似的对象划归成一个类。
成员变量(属性):对象共同的特征的描述

成员变量和局部变量的对比
成员变量(属性):
1)声明在类中,是对象的成员;
2)存放于堆区,在对象被创建的时候就已经初始化有了默认值

作用域:1)声明过后,成员方法都可以使用

局部变量:1)声明在方法或者语句块中;2)存在在栈区

成员方法:  1)只有实例化后才可以使用(就是创建对象 new  xxx)

注意:  
1)成员属性和成员方法只有在实例化之后才能调用
2)在创建对象(实例化)时,就已经将所有的成员变量初始化,赋予了初始值

创建对象:
1)对象就是类的实体,是具体的实例
2)类就是用来产生对象的模板
3)只要看到有new才创建对象

在堆内存中创建了一个实例(对象),引用s1在栈内存中的存放该对象的内存地址

2、方法的递归

方法的递归:自己调用自己
在这里插入图片描述

3、垃圾回收机制

垃圾回收机制:
1)当没有引用指向的时候,该对象就会被当成垃圾被回收;
2)finalize()方法,垃圾回收线程;
3)Java虚拟机的回收机制是达到某一个空间容量就会执行;

4、构造方法

构造方法(构造器):
1)方法名和类名相同
       public class xxx(){} 则其方法名为public xxx(){无参构造},public xxx(int a){有参构造}
2)没有返回值也没有void    
3)一般用public来修饰
4)在Java中,每个类都至少要有一个构造器
5)当你新建的一个类中没有写构造方法时,其实编译器默认给你添加了无参的构造方法
6)当你的类中,有有参构造时,无参构造则消失

作用:
1)初始化对象,当构造方法执行完成时就完成了对象的创建
2)当你使用new创建一个对象时,调用对应的构造方法先完成对象的初始化工作,再将对象那个创建出来
3)一般用于给成员变量初始化

构造方法可以重载:
1)当你实例化一个对象时会默认调用无参构造方法
2)当你的类中有了一个有参的构造方法时,无参的构造方法就会被删除
3)一般我们在提供有参的构造方法时也会提供一个无参的构造方法


this关键字:
1)this()括号中的参数表示你调用了哪一个构造器 ,只能在代码的第一行
2)只能在本类的构造方法中
3)调用其它重载的构造方法
4)谁创建的对象this就是谁的
在这里插入图片描述

5、类图(课外知识)

在这里插入图片描述

注意: + 代表public - 代表 private # 代表 protected Animal代表类名

public class Animal {
   
   
   public String name;
   private int age;
   protected String trueName;
   String sex;
   public String getName() {
   
   
         return name;
   }
   private void setName(String name) {
   
   
         this.name = name;
   }
}

6、包名命名规范

包名命名规范:
1)在同一个包中,类不能同名
2)包允许将类组合成较小的单元
       有助于避免命名冲突
       包允许在更广的范围内保护类、数据和方法

3)若要使用到不在本包的类时,则需要导包import 包名.类名
4)将类放入包中,语法为:package 包名 ;
5)在java中位于包中的类,在文件系统中的存放位置,
        必须有与包名层次相对应的目录结构
       每个源文件只能声明一个包
       java中的层次结构对应操作系统中的文件系统
6)Java类库中常用的包:
       java.lang
           Java默认包,任何程序中,该包都被自动导入。
       java.io
           输入/输出操作有用的类的组成。
7)[面试题]package语句作为java源文件的第一条语句  如果没有package语句,则默认为无名包java.lang不需要手动导入,任何时候jdk面向独享编程自动导入该包

7、构造代码块

8、静态代码块

public class Static {
   
   
	      int age;
	      static int price;
	      public Static() {
   
   
	             this(12);// 调用有参构造,无参构造器失效
	            {
   
   
	                   System.out.println("构造代码块");
	            }
	            System.out.println("无参构造");
	      }
	      public Static(int age) {
   
   
	            this.age = age;
	            System.out.println("有参构造");
	      }
	      static {
   
   
	            price = 50;
	            System.out.println("静态代码块");
	      }// 静态代码块在类加载的时候就已经加载到内存了
	      public static void Static() {
   
   
	            System.out.println("静态方法");
	      }
	      public static void main(String[] args) {
   
   
	            Static s = new Static();
	            s.Static();//调用静态方法,又加载一遍
	      }
	}
结果:
静态代码块
有参构造
构造代码块
无参构造
静态方法
构造代码块:永远放在对象实例化对应的构造器的第一行,会默认放上构造器中
成员代码块 :初始化成员
对象实例化的过程:静态代码块-->构造代码块-->构造方法
实例化多少个对象就调用多少次构造代码块

9、访问修饰符

访问修饰符可用于属性和方法

10、static关键字

static关键字 :静态在类中声明,属于类级别,静态资源在类加载的时候就被初始化了

static修饰变量:类变量(静态变量)
static修饰方法:类方法(静态方法)
调用方式:通过类名直接调用,也可以通过实例化过后的对象引用进行调用
注意:
1)静态方法不能修饰构造器   为什么?
  由于static修饰的方法在类加载的时候就完成初始化工作,构造器时在创建对象的时候才调用
2)静态方法中不能使用this关键字
3)静态方法里只能直接访问静态属性和方法,而不能直接访问类中的非静态属性和方法
4)静态方法不能调用成员属性和成员方法 :因为成员方法在实例化之后才能被调用,而静态方法类加载时就完成初始化

static代码块:
1)静态代码块 --完成静态属性的初始化工作
2)类加载在实例化之前就已经完成了,并且类只加载一次,但是可以实例化多次
3)当jvm虚拟机运行时会找到该类对应的.class文件加载到内存中,会初始化静态资源,自动调
4)用静态代码块完成静态变量的初始化工作
5)静态代码块:在类加载的时候自动执行

成员变量:对象级别,只能实例化过后才能调用,在对象被创建时才初始化不属于某个对象,而是所有对象共享

成员方法:对象级别,只能实例化过后才能调用,在对象被创建时才初始化

静态方法:王室   王室不访问平民

成员方法:平民   平民访问王室

11、super关键字

super关键字:
1)super会默认添加在构造器的第一行,只能出现在子类的构造器中,且必须是第一行
2)super():父类的空的构造方法
3)super()和this()不能同时出现在一个构造器中

注意:
1)实例化子类时,会默认先调用父类的空的构造方法,如果父类中没有空的构造方法时就会编译出错
2)super()中的参数,决定了调用父类哪个构造器
3)构造器只有初始化对象的作用,没有创建对象的作用,只有看见new才会创对象,构造器执行完成时就是对象创建完成的标志

super和this关键字:

super. 指向父类的引用
1)通过关键字super我们可以指定子类在构造时调用父类的哪个构造器,达到先初始化父类然后实例化子类的目的。

2)子类的构造器默认的调用父类无参构造器,即子类构造器中没有用super指明调用父类哪个构造器的话,实际上编译器会自动的在子类构造器第一行加入代码super( );

this.指向本类的引用

1)我们知道子类在实例化时必须调用父类的构造器,实际上有的子类构造器也可以先调用本类的其他构造器,然后再通过那个构造器调用父类的构造器

2)无论是调用父类的构造器还是子类的构造器,最终都是找到最顶级的父类自上而下将父类初始化再实例化子类。只要中间环节有一个构造器没找到,这个子类就无法完成实例化。

12、单例模式

单例模式:
保证一个类在内存中只存在一个实例
1)提供一个私有构造器
2)提供一个私有的静态的自身属性的变量
3)提供一个静态的返回自身类型的方法--全局访问点 public
public class TestInstance {
   
   
	    private TestInstance() {
   
   
	          System.out.println("构造器");
	    }
	    //懒汉式
	    /*private static TestInstance testInstance;
	   
	    public static TestInstance getInstance() {
	          if(testInstance==null) {
	               testInstance=new TestInstance();
	          }
	          return testInstance;
	         
	    } */
	    //饿汉式
	    private static TestInstance testInstance=new TestInstance();
	   
	    public static TestInstance getInstance() {
   
   
	          System.out.println(testInstance);
	          return testInstance;
	    }
	   public static void main(String[] args) {
   
   
	       //懒汉式
	         /* TestInstance t1=new TestInstance();
	         TestInstance t2=new TestInstance();
	         System.out.println(t1==t2);//false*/
	       //饿汉式
	          TestInstance
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值