JAVA基础

  • Program Files:如果安装的软件是64位,则会默认安装到该目录下
  • Program Files(x86):如果安装的软件是32位,则会默认安装到该目录下
  • 软件工程师:
    • 是一种职位的名称,通常是通过计算机的“某种编程语言”完成软件的开发
  • Java软件工程师:通过Java编程语言完成软件的开发,通常是开发应用软件
  • 计算机包括两部分:
    • 硬件:鼠标、键盘、显示器、主机箱内部的CPU、内存条、硬盘等
      • 注意计算机只有硬件是无法工作的,需要有软件驱动硬件才能工作
    • 软件:系统软件和应用软件
      • 系统软件:直接和硬件交互的软件,例如Win7、Winxp、Win8、Win10、Linux操作系统
      • 应用软件:应用软件通常运行在系统软件中,例如qq运行在Windows操作系统上,qq就是应用软件,Win7就是系统软件
  • Windows常见DOS命令(在最初的windows计算机中没有图形界面,只有DOS命令窗口):
    • exit—退出当前DOS窗口
    • cls(clear screen)—清屏
    • dir(directory)—列出当前目录下的子文件/子目录
    • cd(change directory) 相对路径/绝对路径—改变目录
      • 绝对路径:表示该路径从某个磁盘的盘符下作为出发点的路径
      • 相对路径:表示该路径从当前所在的路径下作为出发点的路径
    • cd..—回到上级目录(..也是相对目录,.也是相对目录)
    • cd\—回到根目录
    • cd..\..\:回到指定的上级目录
    • d:  c:  f:—切换盘符
    • mkdir(make directory)  目录名称—创建文件夹
    • del— del命令可以指定的文件而不能删除文件夹,eg:del  *.class(支持模糊匹配)
    • Tab键——自动补全
  • 怎么查看本机的IP地址?什么是IP地址?有什么用?
    • A计算机在网络中要想定位到(连接到)B计算机,那么必须要先知道B计算机的IP地址,IP地址也可以看做计算机在同一个网络当中的身份证号(唯一标识)
    • ipconfig(ip地址的配置信息)
    • ipconfig /all 该命令后面添加一个-all参数可以查看更详细的网络信息,这个详细的信息中包括网卡(要上网就需要网卡)的物理地址,例如:0A-00-27-00-00-06,这个物理地址具有全球唯一性,物理地址通常叫做MAC地址
    • 把自己家的所有人的MAC地址绑定到路由器上就可以防止别人家的蹭网
  • 怎么查看两台计算机是否可以正常通信?
    • ping命令
    • 语法格式:ping  IP地址/ping  域名(www.baidu.com)    域名底层最终还是会被解析成IP地址的形式
    • ping www.baidu.com -t   加上-t参数表示一直访问
  • 快捷键:
    • alt+table—应用之间快速切换
    • window+d—切换到桌面
    • window+l—锁屏
    • window+r运行窗口
    • tab—向右缩进
    • shift+table—向左缩进        
  • 文本编辑器快捷键:
    • 复制  ctrl+c
    • 粘贴  ctrl+v
    • 剪切  ctrl+x
    • 保存  ctrl+s
    • 撤销  ctrl+z
    • 重做  ctrl+y
    • 全选  ctrl+a
    • 查找  ctrl+f
  • 计算机语言(也叫计算机编程语言:用来编写程序)的发展:
    • 什么是计算机编程语言?
      • 提前的人为的制定好的一套交流规则,有的时候,有的语法需要死记硬背,不需要问为什么,只要遵循这套语法规则,那么程序员和计算机之间就可以很好的交流。这就是计算机编程语言。计算机编程语言有很多,例如:C语言、C++、Java、PHP.......
    • 计算机语言发展史
      • 第一代语言—机器语言(执行效率最高,不需要编译,计算机可以直接识别):主要编写二进制码。直接编写101010001这样的二进制,以打孔机为代表
        • 计算机是由电流驱动的,电流只能表示两种状态:正、负,而正可以表示1,负对应0,101010001这些二进制代码正好和自然世界中的十进制存在转换关系,所以计算机可以模拟现实世界当中的事物
      • 第二代语言—低级语言:主要以汇编语言为代表,在低级语言中已经引入了一些英语单词,例如变量赋值:mov a to b;
      • 第三代语言—高级语言:几乎和人类语言完全相同,即使没有学习过计算机编程,只要看到这段代码就知道该代码完成什么功能,例如C语言(面向过程)、C++(半面向过程、半面向对象)、JAVA(纯面向对象,底层C++)
    • 总之,编程语言的发展方向是向着人类更加容易理解的方向发展
  • JAVA语言的发展史:
    • JAVA诞生于1995年
    • 1995年之前,SUN公司(太阳微电子公司:该公司目前被Oracle(甲骨文:做数据库的)收购)为了占领智能电子消费产品(电冰箱、电饭煲、吸尘器等的内核程序)市场,派James Gosling领导团队开发了一个Oak(橡树)语言
    • 1996年,JDK1.0诞生
  • Java包括三大块:
    • JAVASE(Standard Edition):JAVA标准版
    • JAVAEE(Enterprise Edition):JAVA企业版
    • JAVAME(Micro Edition):JAVA微型版
      • java诞生十周年的时候改了名字原来叫J2SE、J2EE、J2ME是因为在java1.2的时候分成了这几个部分,但后来版本一直升级,所以还叫这个不合适
  • JAVA语言的特性:(开源、免费、纯面向对象、跨平台)
    • 简单性:相对而言,JAVA不支持多继承,C++支持多继承,多继承比较复杂,JAVA屏蔽了指针的概念,C++有指针,JAVA语言底层是C++实现的(C++/C程序员可以直接用指针操作内存,更灵活,Java中真正操作内存的是JVM)
    • 面向对象:JAVA是纯面向对象的,更符合人的思维模式,更容易理解
    • 可移植性:JAVA程序可以做到一次编译,到处运行,也就是说JAVA程序可以在Windows操作系统上运行,不做任何修改,同样的JAVA程序也可以放到Linux操作系统上运行,这个被称为JAVA程序的可移植性,或者叫做跨平台性(因为有JVM,不同操作系统有不同版本的JVM,JVM屏蔽了底层操作系统之间的差异,JVM底层是C++编写的)
      • windows操作系统的内核和linux操作系统的内核肯定不同,他们这两个操作系统执行指令的方式也是不一样的,所以Java程序不能直接运行在操作系统上
      • 生成的字节码文件一样,但jvm不一样,生成的二进制指令不同,操作系统只能识别二进制
    • 多线程:java完全/完美支持多线程这种并发机制
    • 健壮性:自动垃圾回收机制(GC—garbage collection)有关,JVM负责调用(垃圾回收器并不是有垃圾立马就回收,达到一定程度才会清理,所以缺点就是内存得不到及时的清理,优点是防止内存溢出,C++可能会导致内存泄漏,最终导致内存溢出)
    • 安全性:开放源代码,所以有漏洞大家就可以修改,更安全,也会更健壮 ,自动垃圾回收机制,防止了内存的泄露,更安全
      • 内存溢出:是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。
      • 内存泄漏:是指程序在申请内存后,无法释放已申请的内存空间,最终导致内存溢出,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。
  • JVM不能单独安装,JDK、JRE可以单独安装
  • JAVA的加载与执行:
    • JAVA程序的运行包括两个非常重要的阶段:
      • 编译阶段:
        • 编译阶段的任务是检查JAVA源程序是否符合JAVA语法
          • 符合JAVA语法则能生成正常的字节码文件
          • 不符合JAVA语法规则则无法生成字节码文件
        • 字节码文件中不是纯粹的二进制,这种文件无法在操作系统当中直接执行
        • javac   java源文件的路径
        • javac是一个Java的编译器工具
        • JDK = JRE + 开发工具集(例如Javac编译工具等)

          JRE = JVM + Java SE标准类库+运行工具集(例如Java运行工具等)

      • 运行阶段
        • java 类名(注意:java后面跟的不是文件的名称,是类名)(运行需要先切换到Java字节码文件所在目录)
        • java.exe命令会启动java虚拟机(JVM),JVM 会启动类加载器ClassLoader
        • ClassLoader会去硬盘上搜索A.class文件,找到该文件则将该字节码文件装载到JVM当中 
        • JVM对A.class字节码文件进行解释(将字节码解释成101010001这样的二进制)
        • 然后操作系统执行二进制和底层硬件平台进行交互
  • Windows操作系统是如何搜索硬盘上的某个命令呢
    • 首先会从当前目录下搜素
    • 当前目录搜索不到,会从环境变量path指定的路径当中搜索某个命令
    •  如果都搜索不到,则报错
      • 注意:path环境变量和Java语言没有关系,path环境变量是属于windows操作系统的一个知识点,path环境变量是专门给Windows操作系统指路的
    • 环境变量改变必须重启DOS命令窗口
  • 对于Java的JDK所属的环境变量,有一个叫做JAVA_HOME,但这个Java_HOME目前我们不需要,不配置这个环境变量也不会影响当前程序的运行,但是后期学习到JAVA_WEB的时候需要安装Tomcat服务器,那个时候JAVA_HOME就必须配置了
  • 环境变量classpath(大小写无所谓,但必须叫classpath)
    • 当classpath环境变量配置为某个指定的路径之后,类加载器只去指定的路径当中加载字节码文件,所以classpath不再配置,这样类加载器会自动从当前路径下加载class字节码文件,所以,每一次执行.class程序时候,需要在DOS命令窗口中先切换到.class字节码文件所在的路径下,然后运行,当然classpath也可以这样配置,classpath=.;otherpath
    • classpath是专门为类加载器指路的
  • Java源程序当中的注释:(一个好的开发习惯应该是多编写注释,这样程序的可读性增强)
    • 注释出现在JAVA源程序当中,对JAVA源代码进行解释说明
    • 注释不会被编译到.class字节码文件当中
    • 单行注释 //     多行注释/*  */       javadoc注释/**    *   *   */
    • 文档注释,这种注释是比较专业的,该注释信息会被javadoc.exe工具解析提取并生成帮助文档
  • Java语言中语句一般有两种结束方式:以分号;或后大括号}结束,以}结束的一般为流程控制语句。

  • public class和class的区别:
    • 一个Java文件中可以定义多个class
    • 一个Java源文件当中public的class不是必须的
    • 一个class会生成一个xxx.class字节码文件
    • 一个Java源文件当中的定义公开的类的话,只能有一个,并且该类名称必须和Java源文件保持一致
    • 每个class当中都可以编写main方法,都可以设定程序的入口,如果没有主方法,会出现运行阶段的错误
  • 标识符
    •  什么是标识符
      • 在Java源程序当中凡是程序员有权利自己命名的单词都是标识符
    • 标识符的命名规则:
      • 只能由字母(包括中文)(A-Z、a-z)、数字(0-9)、下划线_、美元符号$组成,不能含有其他符号
      • 不能数字开头
      • 严格区分大小写
      • 关键字不能做标识符 
    • 标识符的命名规范:
      • 最好见名知意
      •  遵循驼峰命名方式
        • 类名、接口名:首字母大写,后面每个单词的首字母大写
        • 变量名、方法名:首字母小写,后面每个单词首字母大写
        • 常量名:全部大写,单词之间用下划线分开
        • 包名:全部小写
      • 理论上无长度限制,但最好不要太长
  • 关键字:
    • 在SUN公司开发Java语言的时候,提前定义好的一些具有特殊含义的单词,这些单词全部小写,具有特殊含义,不能用作标识符
  • 字面值:
    • 字面值就是字表面的值,包括:整型、浮点型、字符型、字符串型、布尔型
    • 字面值就是数据
    • 字面值是Java源程序的组成部分之一,包括标识符和关键字他们都是Java源程序的组成部分
  • 变量:
    • 变量本质上是内存中的一块空间,这块空间有"数据类型"、"名称"、"值"
    • 变量是内存中存储数据的最基本的单元
    • 变量只有在赋值之后内存空间才开辟出来
      • 赋值运算符先计算等号右边的表达式,然后将结果赋值给左边
    • 在同一个作用域中,变量不能重名,在不同的作用域中,变量可以重名,类体和方法体属于不同的作用域,但是变量遵循就近原则
    • 局部变量只在方法体当中有效,方法执行结束该变量的内存就释放了
  • 数据类型的作用: 
    • 是指导JVM在程序运行的时候给该数据分配多大的内存空间
  • 基本数据类型的分类(四大类,八小种):byte、short、int、long、float、double、boolean、char    1、2、4、8、4、8、1、2
    • 整型(byte、short、int、long)
    • 浮点型(float、double)
    • 字符型(char)
    • 布尔型(boolean)
  • 计算机在任何情况下都只能识别二进制,例如:10101010100101...,现代计算机底层采用交流电的方式,就接通和断开两种方式,所以计算机只识别1和0,其他不认识
  •  字符编码:
    • 起初的时候计算机不支持文字,只支持科学计算,实际上计算机起初是为了战争而开发的,计算导弹的轨道
    • 为了让计算机可以表示现实世界当中的文字,我们需要人为地干涉,需要人负责提前制定好“文字”和“二进制”之间的对照关系,这种对照转换关系被称为“字符编码”
    • 计算机最初只支持英文,最先出现的字符编码是:ASCII码 (采用一个字节编码)
      • 'A'—65
      • 'a'—97   'a'----(按ASCII编码)----01100001     01100001----(按ASCII解码)----'a'
      • '0'—48
        • 编码和解码采用同一套字典/对照表,不会出现乱码
        • 编码和解码采用的不是同一套字典/对照表,会出现乱码
    • 随着计算机的发展,后来出现了一种编码方式,是国际化标准组织ISO制定的,这种编码方式支持西欧语言,向上兼容ASCII码,仍然不支持中文,这种编码方式是ISO-8859-1(1字节),又被称为latin-1
    • 随着计算机向亚洲的发展,计算机开始支持中文、日文、韩文等国家的文字,其中支持简体中文的编码方式:GB2312<GBK<GB18030(容量关系)
    • 支持繁体中文:大五码<big5>
    • 后来出现了一种编码方式统一了全球的所有文字,容量较大,这种编码方式叫做:unicode编码,unicode编码方式有多种具体的实现:UTF-8、UTF-16、UTF-32,Java语言源代码采用的是unicode编码方式,所以“标识符”可以写中文
  • 数据类型的取值范围:
    • byte     ——1字节——  -128-127
    • short    ——2字节——  -32768-32767
    • int        ——4字节——  -2147483648-2147483647
    • char     ——2字节——   0-65535
    • boolean——1字节——   true/false
    • 注意:short和char所表示的种类总数是一样的,只不过char可以表示更大的正整数,因为char没有负数
  • 数据类型的默认值:
    • 数据类型                                              默认值
    • ---------------------------------------------------------------
    • byte、short、int、long                          0
    • float、double                                         0.0
    • boolean                                                  false(true是1,false是0)
    • char                                                        \u0000
  • 转义字符 \:
    • \n   换行符
    • \t    制表符
    • 转义字符出现在特殊字符之前,会将特殊字符转换为普通字符
      • \'    普通的单引号
      • \\    普通的反斜杠(将转义字符转换成普通的反斜杠)
      • \''    普通的双引号
        • 补:char a='';//Java中不允许这样编写程序,编译报错
        • 补:JDK中自带的native2ascii.exe命令,可以将文字转化成Unicode编码形式
        • 补:char a='\u0000',值是0,输出是空白字符
        • \u4e2d,反斜杠u联合起来后面一串数字是某个文字的unicode编码,这个编码是十六进制的
    • 转义字符单独写后面只能跟这几种,要是跟其他的,必须写成\\转换成普通字符,否则是报错
  • println()表示输出之后换行,print()表示输出之后不换行
  • 整型
    • Java语言当中的“整数型”字面值被默认当做int类型来处理,要让这个“整数型”字面值被当做long类型来处理的话,需要在整数型字面值后面添加l/L,建议使用大写的L(所有数据在计算机内部都是以补码形式存放的)
    • 正数的原码、反码、补码都一样,负数的补码等于符号位不变,其他部分按位取反再加一,所以,知道负数的补码求原码,先减一,符号位不变,其它部分按位取反
    • Java语言中整数型字面值的四种表示方式:
      • 十进制(最常用,缺省默认方式)
      • 八进制(以0开始)
      • 十六进制(以0x开始)
      • 二进制(以0b开始)
  • 浮点型
    • double的精度太低(相对来说),不适合做财务软件, 财务涉及到钱的问题,要求精度较高,所以SUN在基础SE类库当中为程序员准备了精确度更高的类型,只不过这种类型是一种引用数据类型,不属于基本数据类型,它是java.math.BigDecimal
      • SE类库的字节码:D:\app\java\jre\lib\rt.jar
      • SE类库源码:D:\app\java\src.zip
    • double和float在计算机内部二进制存储的时候存储的都是近似值,在现实世界中有些数字是无限循环的,例如3.333333333.........,但计算机的资源是有限的,用有限的资源存储无限的数据只能存储近似值
    • Java语言当中的“浮点型”字面值被默认当作double类型来处理,要想该字面值被当作float类型来处理,需要在字面值后面添加F/f
  • 布尔型
    • 在Java语言当中boolean类型只有两个值,true和false,没有其他值,不像C语言当中,0和1可以表示假和真,但其实底层还是0和1
  • 关于基本数据类型之间的相互转化,转换规则:
    • 八种数据类型当中除了布尔数据类型之外,剩下的7种类型之间都可以进行相互转换
    • 小容量向大容量转换,称为自动类型转换,容量从小到大排序:
      • byte<short(char)<int<long<float<double
        • 任何浮点类型不管占用多少个字节,都比整型容量大
        • char和short表示的种类数量相同,但char可以取更大的正整数
    • 大容量转换成小容量,叫强制类型转换,需要加强制类型转换符,程序才能编译通过,但是在运行阶段可能会损失精度,所以要谨慎使用
      • 强制类型转换其实就是将左边砍掉
    • 当整数字面值没有超过byte、short、char的取值范围,可以直接赋值给byte、short、char类型的变量
    • byte、short、char混合运算的时候,各自先转换成int类型在做运算
      • int i=10;  byte b=i/3;   //错误,因为编译期只检查语法错误,运行的时候才会赋值和运算
    • 多种数据类型混合运算,先转换成容量最大的那种类型再做运算
  • 运算符(一个表达式当中有多个运算符,运算符有优先级,不确定的加小括号,优先级得到提升)
    • 算术运算符             +、-、*、/、++、--、%(求余数,取模)
    • 关系运算符             <、<=、>、>=、==、!=
          • 关系运算符的结果一定是布尔类型
          • 关系运算符比较的都是值的大小
    • 布尔运算符             &&(短路与)、||、&(逻辑与)、|、!(逻辑非)、^(相同为假,不同为真)(逻辑异或 )
          • 逻辑运算符要求两边的算子都是布尔类型,并且逻辑运算符最终的结果也是一个布尔类型
          • 短路与和逻辑与最终运算结果都是相同的,只不过存在短路现象
          • 短路或和逻辑或最终运算结果都是相同的,只不过存在短路现象
          • 短路与和短路或由于后面的表达式可能不执行,所以执行效率较高,在实际开发中使用较多
    • 位运算符(用来直接操作二进制)                 
          • &按位与(同真则真,有假则假)
          • |按位或(同假则假,有真则真)
          • ^按位异或(相同为假,不同为真)
          • ~按位非(真则假、假则真)
          • >>右移(有符号右移,正数补0,符数补1)
          • >>>右移(无符号右移,必须补0)
          • <<左移
    • 赋值类运算符          =、+=、-=、*=、/=、%=、^=、&=、|=、<<=、>>=
          • 扩展类的赋值运算符不改变运算结果类型
    • 字符串连接运算符   +
    • 条件运算符              ?:
    • 其他运算符               instanceof、new
  • 控制台上输出的都是字符串
  • 控制语句(所有的控制语句都可以嵌套,但注意缩进,大括号里面套的大部分要缩进):
    • 控制选择结构语句:
      • if(第一种)、if.....else....(第二种)(if语句分支中只有一条java语句,{}可以省略不写)
        • 第三种(用区间理解)
          • if(布尔表达式){
          • 分支1;
          • }else if(布尔表达式){
          • 分支2;
          • }else if(布尔表达式){
          • 分支3;
          • }
        • 第四种
          • if(布尔表达式){
          • 分支1;
          • }else if(布尔表达式){
          • 分支2;
          • }else if(布尔表达式){
          • 分支3;
          • }else{
          • 分之4
          • }
        • 例子
          •  

      • switch(int或String)//byte、short、char也是可以的
      • switch(i){
      • case 1: case 2: case 3: case 4:
        • System.out.println("4");
        • break;
      • //case合并
      • case 5:
        • System.out.println("5");
        • break;
      • default :
        • java语句;
      • }
        • case要顶格写 
        • JDK6,switch和case后面只能写int
        • JDK7之后包括7,switch和case后面可以写int或String
        • 区间的判断用if比较合适,固定值用switch比较合适
    • 控制循环结构语句:
      • for(初始化表达式;布尔表达式;更新表达式都可以不写,但;必须写)
        • 先执行初始化表达式,只执行一次,然后执行布尔表达式,布尔表达式为true,执行循环体,然后执行更新表达式,然后执行布尔表达式,布尔表达式为true,执行循环体
      • while
      • do....while(); //分号一定不能少了   
    • 转向语句(改变控制语句顺序):
      • break
        • break+“;”可以成为一个单独的完整的java语句
        • break终止的是离他最近的循环,也可以通过给for循环起名字来终止自定义的for
        • 可以用来终止switch语句,防止case穿透现象
        • return:return所在的方法结束,但不是JVM结束
      • continue
        • continue+“;”可以成为一个单独的完整的java语句
        • continue跳过的是离他最近的循环,也可以通过给for循环起名字来跳过自定义的for
  • 定义:某自然数除它本身以外的所有因子之和等于该数,则该数被称为完数。所以1不是完数,最小的完数是6,6=1+2+3
  • 接收用户键盘输入:
    • java.util.Scanner s = new java.util.Scanner(System.in);//创建键盘扫描器对象
    • s.nextInt();//用来输入整数
    • s.next();//用来输入字符串
  • 在JVM内存划分上有三块主要的内存空间(当然除了这三块还有其他的内存空间)
    • 栈内存stack
    • 堆内存heap
    • 方法区内存
  • 关于数据结构
    • 程序=数据结构(存储数据的容器)+算法(排序算法、查找算法..........)
    • 数据结构反映的是数据的存储形态
    • 数据结构是独立的学科,不属于任何编程语言范畴,只不过大多数编程语言中要使用数据结构
    • 作为程序员需要提前精通:数据结构+算法
    • 常见的数据结构:
      • 数组
      • 队列
      • 链表
      • 二叉树
      • 哈希表/散列表
  • 栈数据结构:
    • 栈数据结构的特点:先进后出、后进先出
    • 处于栈顶部的元素具有活跃权
    • 不管是静态方法、实例方法、构造方法,他们在运行的时候都需要压栈
  • 方法的本质:方法就是一段代码片段,并且这段代码片段可以完成某个特定的功能,并且可以被重复使用
  • 只要带有return关键字的语句执行,return语句所在的方法结束(不是JVM结束,是return所在的方法结束),在同一个域中,return语句下面不能编写任何代码,因为永远执行不到
  • 方法只定义不去调用是不会执行的,并且JVM中也不会给该方法分配运行所属的内存空间,只有在调用的时候才会执行,栈内存中分配方法运行的所属内存空间
  •  方法代码片段存在哪里?方法执行的时候执行过程的内存在哪里分配?

    • 方法代码片段属于.class字节码文件的一部分,字节码文件在类加载的时候被放到方法区当中,所以JVM中的三块主要的内存空间中方法区内存最先有数据、存放了代码片段。
    • 代码片段虽然在方法区当中只有一份,但是可以被重复调用,每一次调用这个方法的时候,需要给该方法分配独立的活动场所,在栈内存中分配,方法在调用的瞬间,会给该方法分配内存空间,会在栈中发生压栈动作,方法执行结束之后,给该方法分配的内存空间全部释放,此时发生弹栈动作   
    • 局部变量在栈中的方法体中分配内存,方法执行结束,局部变量的内存空间就释放了   
  • 方法重载(overload)
    • 什么时候考虑使用方法重载?
      • 功能相似的时候,尽可能使用方法重载
    • 什么条件满足之后构成方法重载?
      • 在同一个类中
      • 方法名相同
      • 参数列表不同:
        • 个数不同
        • 顺序不同
        • 类型不同
    • 方法重载和什么有关系?和什么没有关系?     
      • 方法重载和方法名+参数列表有关系
      • 方法重载和返回值类型无关
      • 方法重载和修饰符列表无关       
    • java支持方法的重载机制,有些不支持,例如以后要学习的JavaScript就不支持 
  • 递归调用 
    • 什么是递归?
      • 递归就是方法自己调用自己
    • 递归是很耗费栈内存的,递归算法可以不用的时候尽量别用
    • 递归必须有结束条件,没有结束条件一定会发生栈内存溢出错误StackOverflowError,错误发生无法挽回,只有一个结果就是JVM停止工作
      • 在实际的开发中,假如有一天你真正遇到了:StackOverflowError,怎么解决这个问题?
        • 首先第一步,检查递归的结束条件对不对,如果递归结束条件不对,必须对条件进一步修改,直到正确为止
        • 如果条件没问题,就需要手动调整JVM的栈内存的初始化大小,可以将栈内存的初始化调大一些,如果调整了还是出现这个错误,就继续调大
          • java -X可以查看堆栈大小的参数
    • 递归即使有了结束条件,即使结束条件是正确的,也可能会发生栈内存溢出错误,因为递归的太深了   
    • 在实际的开发中,不建议轻易选择递归,能用for循环while循环代替的,尽量选择循环来做,因为循环的效率高而且耗费的内存少,递归耗费的内存比较大,另外递归的不当,JVM会死掉,(但在极少数情况下,不用递归,这个程序没法实现),但是有些情况下该功能的实现必须依靠递归方式,例如:目录拷贝
  • 太计较变量的数量会有什么后果:(运行效率不会变低)
    • 后果一:代码的可读性差
    • 后果二:可读性差也会牵连到代码的开发效率
  • eclipse快捷键:
    • ctrl+/           单行注释的 注释和取消注释
    • ctrl+shift+/  多行注释  ctrl+shift+\   多行注释的取消
    • ctrl+shift+f  格式化代码
    • ctrl+d          删除一行
    • 当一个类的成员变量和方法特别多的时候,可以ctrl+o输入要查找的元素快速查找
    • ctrl+shift+t  查找类型  查找所有的类
    • ctrl+s hift+r  查找资源  查找该项目中的资源,例如db.properties
    • ctrl+shift+o 快速导入包的快捷键
  • 面向对象
    • 面向对象和面向过程的区别     
      • 面向过程(主要关注的是实现的具体过程,因果关系)耦合度高,扩展力差
        • 优点:对于业务逻辑比较简单的程序,可以达到快速开发,前期投入成本低,不需要前期进行对象的提取,模型的建立
        • 缺点:采用面向对象的方式开发很难解决非常复杂的业务逻辑,另外面向过程的方式导致元素之间的耦合度非常高,只要其中一环出问题,整个系统受到影响,另外没有独立体的概念,无法达到组件复用
      • 面向对象(主要关注的是对象—独立体能完成哪些功能)耦合度低,扩展力强   
        • 优点:耦合度低,扩展力强,更容易解决现实世界当中更复杂的业务逻辑,组件复用性强
        • 缺点:前期投入成本较高,需要进行独立体的抽取,大量的系统分析与设计 
        • 面向对象成为主流的原因是面向对象更符合人的思维方式      
    • 面向对象三大特征
      • 封装
      • 继承
      • 多态
      • 任何一个面向对象的编程语言都包括这三个特征,python也有   
    • 采用面向对象的方式开发一个软件,生命周期:
      • 面向对象分析:OOA
      • 面向对象设计:OOD
      • 面向对象编程:OOP   
    • 对象抽象化成类,类实例化成对象,对象也叫做实例
    • 类的结构
      • [修饰符列表] class 类名{
      •     属性;//描述对象的状态信息,名字,身高,性别,年龄,采用变量的方式来定义
      •     方法;//描述对象的动作信息,吃饭,睡觉,学习,采用方法的方式来定义
      • }
  • 对象的创建和使用
    • 不创建对象,成员变量的内存空间不存在,只有创建了对象,成员变量运行时的内存空间才会创建
    • 保存的是对象的内存地址的变量,有一个特殊的名字叫引用
    • 引用是一个变量,可以是局部变量,也可以是成员变量
  • 对于成员变量,没有手动赋值,系统赋默认值:
    • byte                0
    • short               0
    • int                   0
    • long                0L
    • float                0.0F
    • double            0.0
    • boolean          false
    • char                \u0000
    • 引用数据类型  null
  • JVM内存分析
      • 方法区当中的类加载是用到了才会加载,不是一下子全加载
  • 空指针异常:空引用访问实例相关的数据时,会发生空指针异常java.lang.NullPointerException

    • 实例相关的数据,就是数据访问的时候必须有对象的参与,这种数据就是实例相关的数据
  • Java的集成开发环境(集成开发环境简称:IDE):集成开发环境讲究一站式开发,使用这个工具即可,有提示功能,有自动纠错功能
    • 集成开发环境可以让软件开发变得更简单、更高效
    • 没有IDE工具:
      • 需要安装JDK、需要配置环境变量、需要手动的将Java源文件编译生成class字节码文件
      • Java源程序出错之后还没有提示
      • 代码没有自动提示功能
    • 有IDE工具:
      • 不需要独立安装JDK、不需要手动手动配置环境变量、不需要使用javac命令对Java源程序进行编译
      • Java源程序出错之后马上有提示
      • 代码有自动提示功能
    • Java中有哪些比较牛的IDE呢?
      • eclipse(最多)【日食】
        • IBM团队研发的,主要是为了吞并SUN公司,但SUN公司后来被Oracle收购了
        • workspace:工作区(工作区当中的基本单元是Project(项目/工程))
          • 当myeclipse打开的时候,会提示选择工作区
          • 这个工作区可以是已经存在工作区,也可以是新建的工作区
          • 选择工作区后,将来编写的Java代码,自动编译的class文件都会在工作区当中找的
          • myeclipse可以开启两个甚至更多的会话,每一个会话对应不同的工作区workspace
          • workspace中有一个文件夹.metadata,在该文件夹中存储了当前myeclipse的工作状态,将.metadata文件夹删除之后,下一次在进入这个工作区的时候,是一个全新的开始,但是会发现这个IDE工具中所有的项目丢失了,没关系,这里只是丢失了eclipse的项目,硬盘上真是存储的项目不会丢失
        • 窗口不小心关闭了,可以再次打开:
          • Window->show view->other->输入自己要找的窗口
        • 布局乱了可以:window->prespective->Reset prespective
        • 工程名一般全部小写
        • 重点窗口介绍:
          • Package Explore/Navigator/Project Explore:可以看到java源文件
          • Console:控制台窗口
        • 工作区workspace的基本单元是:Project(工程/项目)
      • myeclipse
        • myeclipse比eclipse有更多的插件,但收费
      • Intellij IDEA(上升的趋势)
        • 与eclipse不同,idea的一个工作区可以反复打开
      • NetBeans
      • JBuilder
  • 面向对象的封装性
    • 封装的好处:
      • 1.封装之后,对于那个事物来说,看不到事物比较复杂的那一面,只能看到该事物简单的那一面。复杂性封装,对外提供简单的操作入口
      • 2.封装之后,对于事物本身,不能之间访问,提高了安全性
    • 封装的步骤:
      • 1.属性私有化,使用private关键字修饰,private表示私有的,修饰的所有数据只能在本类中访问
      • 2.对外提供简单的操作入口,也就是说以后外部程序要想访问age属性,必须通过这些简单的入口进行访问
        • 对外提供两个公开的方法,分别是setXxx()和getXxx()
  • 构造函数:
    • 对于构造方法来说,返回值类型不需要指定,并且也不能写成void,只要写成void,那么这个方法就成为普通方法了
    • 构造方法的方法名必须和类名保持一致
    • 构造方法的作用?
      • 创建对象(和new连用时,才创建对象)
      • 创建对象的同时,初始化实例变量的内存空间
    • 构造方法怎么调用?
      • 普通方法有static关键字是-类名.方法名(实参列表),没有static关键字是-引用.方法名(实参列表)
      • new 构造方法名(实参列表)
    • 构造方法执行结束之后有返回值吗?
      • 有返回值,返回值是构造方法所在类的类型,但是return 值,这样的语句不需要写,Java程序自动返回值,因为构造方法的返回值类型就是类本身的类型
    • 当一个类没有定义任何构造方法,系统默认给该类提供一个默认的构造方法,称为缺省构造器
    • 当一个类提供了有参构造方法,系统将不再提供默认的无参构造方法
    • 构造方法支持重载机制,在一个类当中编写多个构造方法,这多个构造方法显然已经构成了方法重载
  • this
    • 在对象内部,有一个关键字叫this,this中保存的是该对象的内存地址,this指向该对象本身  
    • 当c1去访问这个对象,this就代表c1,当c2去访问这个对象,this就代表c2,this代表当前正在执行这个行为的对象
    • this不能使用在带有static的方法当中
    • this多数情况下是可以省略的,但是区分局部变量和实例变量时不能省略
    • this(实参)表示当前构造方法可以调用本类的其他构造方法,目的是代码复用,并且this(实参)必须出现在构造方法的第一行
    • 如果直接输出this,this会自动调用toString方法,但是super不能单独用
  • super
    • 是一个关键字,全部小写
    • super要和this对比着学:
      • this
        • this能出现在实例方法和构造方法中
        • this的语法,this.、this()
        • this不能使用在静态方法中
        • this.大部分情况下是可以省略的,但在区分局部变量和实例变量的时候不能省略
        • this()必须出现在构造方法的第一行,通过当前构造方法,调用本类其他构造方法,目的是代码复用
      • super
        • super能出现在实例方法和构造方法中
        • super的语法,super.、super()
        • super不能使用在静态方法中
        • super.大部分情况下是可以省略的,但子中有,父中又有(变量和方法),如果想在子中访问父的特征,super.不能省略
        • super()必须出现在构造方法的第一行,通过当前构造方法,调用父类的构造方法,目的是代码创建子类型对象的时候,先初始化父类型特征,例如会给父类的成员变量赋初值
        • 如果直接输出this,this会自动调用toString方法,但是super不能单独用,因为super不是引用,super也不保存内存地址,super也不指向任何对象,super只是代表当前对象内部的那一块父类型的特征
      • 重要结论:
        • 当一个构造方法第一行既没有this(),又没有super()的话,默认会有一个super(),表示通过当前子类的构造方法调用父类的无参数构造方法,所以必须保证父类的无参数构造方法是存在的

        • Object的无参数构造方法一定会执行
        • 子类中定义的成员变量和父类中定义的成员变量相同时,则子类会隐藏父类的成员变量,和方法其实是一样的,此时想访问父类的属性或方法必须加super.
  • static
    • 什么时候成员变量声明为实例变量呢?
      • 所有对象都有这个属性,但是这个属性的值会随着对象的变化而变化,不同对象的这个属性具体的值不同
    • 什么时候成员变量声明为静态变量呢?
      • 所有对象都有这个属性,并且对象的这个属性的值是一样的,建议定义为静态变量,节省内存开销
    • 带有static的方法,既可以采用类名的方式访问,也可以采用引用的方式访问,但是即使采用引用的方式访问,实际上执行的时候和引用指向的对象无关,所以eclipse开发的时候,使用引用的方式访问带有static的方法,程序会出现警告,所以还是建议使用类名的方式访问
    • 静态代码块/静态语句块:
      • static{
      •      java语句;
      • }
      • 静态代码块在类加载的时候执行,并且只执行一次
      • 静态代码块和静态变量都在类加载的时候执行,时间相同,只能靠代码的顺序来决定
      • 静态代码块在一个类中可以编写多个,并且按照自上而下的顺序依次执行
      • 例如项目中要求在类加载的时刻/时机执行代码完成日志的记录,那么这段记录日志的代码就可以编写到静态代码块当中,完成日志的记录
      • 静态代码块是Java为程序员准备的一个特殊的时刻,这个特殊的时刻被称为“类加载时刻”,若希望在此刻执行一段特殊的程序,这段程序可以直接放到静态代码块当中
      • 通常在静态代码块中完成预备工作,先完成数据的准备工具,例如:初始化连接池、解析XML配置文件............
    • 实例代码块/实例语句块:
      • 实例代码块可以编写多个,也是遵循自上而下的顺序依次执行
      • 实例代码块在构造方法执行之前执行,构造方法执行一次,实例代码块对应执行一次
      • 实例代码块也是Java语言为程序员准备的一个特殊时机“对象初始化时机”
    • 到目前为止,你遇到的所有Java程序,有顺序要求的是哪些?
      • 第一,对于方法来说 
      • 第二:静态代码块1和静态代码块2是有先后顺序的
      • 第三:静态代码块和静态变量是有先后顺序的
      • 第四:实例变量和实例代码块是有先后顺序的
    • 方法什么时候定义为静态?
      • 方法描述的是动作,当所有的对象执行这个动作的时候,最终产生的影响是一样的,那么这个动作已经不再属于某一个对象动作了,可以将这个对象提升为类级别的动作
    • class 类{
    •    静态代码块//类加载时执行
    •    实例代码块//构造方法执行之前执行
    •    静态变量//类加载时候赋初值
    •    实例变量//构造方法执行之前赋初值
    •    静态方法//类名.方法名
    •    实例方法//引用.方法名
    •    构造方法//new 方法名
    • }
    • 大多数工具类的方法都是静态方法
  • 继承(extends):
    • 继承的基本作用是代码复用,但是继承最重要的作用是,有了继承,才有了以后的方法的覆盖和多态机制
    • 继承也是有缺点的,父类代码修改,子类受到牵连,使得代码耦合度高
    • Java语言中的继承只支持单继承,一个类不能同时继承很多类,只能继承一个类,在C++中支持多继承
    • 关于继承中的一些术语:
      • B类继承A类:
      • A类称为:父类、基类、超类、superclass
      • B类称为:子类、派生类、扩展类、subclass
    • 在Java语言中子类继承父类都继承哪些数据呢?
      • 私有的不支持继承
      • 构造方法不支持继承
      • 其他的都支持继承
    • 虽然Java语言当中只支持单继承,但是一个类也可以间接继承其他类,例如:
      • C extends B{
      • }
      • B extends A{
      • }
      • A extends T{
      • }
      • C类直接继承B类,但是间接继承A、T类
    • Java语言中假设一个类没有显示的继承任何类,该类默认继承JavaSE库当中提供的java.lang.Object类
    • 当源码中一个方法以;结尾,并且修饰符列表中有native关键字,表示底层调用C++写的dll程序(dll动态链接库)
    • toString方法的Integer.toHexString(hashCode())的值可以等同看作对象在堆内存当中的内存地址,实际上是内存地址经过哈希算法得出的十六进制的结果
  • 回顾方法重载(Overload):
    • 方法重载什么时候用:
      • 当在同一个类中,方法完成的功能是相似的,建议方法名相同,这样方便程序员的编程,就像在调用一个方法似的,代码美观
    • 什么条件满足之后构成方法的重载:
      • 在同一个类中
      • 方法名相同
      • 参数列表不同:类型、个数、顺序
    • 方法重载和什么无关:
      • 和返回值类型无关
      • 和方法的修饰符列表无关
  • 方法的覆盖(方法重写Override/Overwrite):
    • 什么时候使用方法重写
      • 当父类中的方法已经无法满足当前子类的业务需求,子类有必要将父类中继承过来的方法进行重新编写,这个重新编写的过程叫做方法重写
    • 什么条件满足之后会发生方法重写呢?【代码满足什么条件之后就构成方法得覆盖呢?】
      • 方法重写发生在具有继承关系的父子类之间
      • 返回值类型相同,方法名相同,形参列表相同【建议方法重写的时候尽量复制粘贴或者自动生成,不要自己编写,容易出错,导致没有产生覆盖】
        • 返回值类型对于基本数据类型必须一样,对于引用数据类型,覆盖之后的类型可以更小(子类)
        • 访问权限不能更低,只能更高,
        • 抛出异常
          • 对于编译时异常如果都是Exception子类时子类不能比父类不能更多。如果父类是Exception,子类是Exception子类时,多少无所谓
          • 运行时异常怎么样无所谓
    • 注意
      • 私有方法不能继承,所以不能覆盖
      • 构造方法不能继承,所以不能覆盖
      • 静态方法不存在方法的覆盖(因为静态方法和对象没有关系,而且方法覆盖要和多态联合)
      • 覆盖只针对方法,不谈属性
    • 如果一个方法是重写之后的方法,方法前面会有一个绿色的小箭头
  • 多态
    • 关于多态中涉及到的几个概念:
      • 向上转型(upcasting):子类型->父类型   又被称为:自动类型转换
      • 向下转型(downcasting):父类型->子类型  又被称为:强制类型转换
        • 以后在工作中,在和别人聊天时,要专业一些,说向上转型和向下转型,不要说自动类型转换,也不要说强制类型转换,因为自动类型转换和强制类型转换是使用在基本数据类型方面的,在引用类型转换这里只有向上和向下转型
      • 无论是向上转型还是向下转型,两种类型之间必须要有继承关系,没有继承关系,程序无法编译通过
      • 静态绑定:编译阶段的绑定
      • 动态绑定:运行阶段的绑定
    • Animal a=new cat();//父类型引用指向子类型对象,这种程序存在编译阶段绑定和运行阶段绑定两种不同的形态,称为向上转型
    • 什么时候进行向下转型
      • 当调用的方法是子类型中特有的,在父类型中不存在,必须进行向下转型
    • 向上转型,只要编译通过,运行一定不会出问题,Animal a=new Bird();  
    • 向下转型,编译通过,运行可能出现问题,Animal a=new Bird();  Cat c=(Cat)a;编译时候通过了,但是运行时Bird和Cat没有关系,所以发生异常,ClassCastException
    • 怎么避免向下转型出现的ClassCastException呢?
      • 使用instanceof关键字可以避免该异常
    • instanceof关键字怎么用?
      • 引用   instanceof   数据类型名,运算结果可能是true/false
    • 既然眼睛可以看出new的是什么对象,为什么还用instanceof关键字呢
    •  关于运算结果true/false
      • 假设(a instanceof Bird)
      • true表示a这个引用指向的对象是一个Bird类型
      • false表示a这个引用指向的对象不是一个Bird类型
    • 方法覆盖需要和多态机制联合起来使用才有意义
      • 没有多态机制,方法覆盖可有可无
      • 没有多态机制,方法覆盖也可以没有,如果父类的方法无法满足子类的业务需求,子类完全可以定义一个全新的方法
  • 调试程序,选中某一行,然后在最左侧双击产生断点,然后鼠标右击,选择Debug As,跳出调试页面,选中的那一行表示,程序执行到这行,但是这行还没执行
  • 多态的作用:
    • 降低程序的耦合度,提高程序的扩展力(原来Master和Bird、Cat的耦合度太高,通过增加Animal类,降低了Master和Bird、Cat的耦合度)
  • 一定要记住,软件在扩展过程当中,修改的越少越好,修改的越多,系统的稳定性就越差,未知的风险就越多
    • 这里涉及到一个软件开发原则
      • 软件开发原则有七大原则(不属于java,这个开发原则属于整个软件业):其中有一条最基本的原则:OCP(开闭原则)
      • 什么是开闭原则?
        • 对扩展开放(可以额外添加),对修改关闭(最好很少的修改现有的程序)
  • final
    • final是一个关键字,表示最终的,不可变的
    • final修饰的类无法被继承
    • final修饰的方法无法被覆盖 
    • final修饰的变量一旦赋值之后,不可重新赋值
      • final修饰的实例变量,必须手动赋值,不能采用系统的默认值
        •  第一种解决方案:final int num=10;
        • 第二种解决方案:final int num;  public 构造方法名 () { this.num=200; }
      • final修饰的引用虽然指向某个对象之后不能指向其他对象,就算赋值null也不行,所以无法被垃圾回收器回收,但是,所指向的对象内部的数据是可以被修改的
        • final User user=new User(30);
        • user.id=50;
    • final修饰的变量,每个对象都有一份,只是值不能改变,存放在堆中,但加上static后,存放在方法区中,所有对象共用一份,节省空间。
    • 既有static又有final的叫做常量
  • 链接源码:Attach Source
    • WorkSpace表示源码在工作空间中
    • External File表示源码在压缩包中
    • External Folder表示源码在文件夹中
  • 大家学习的类库,一般都是包括三个部分的:
    • 源码【可以看源码来理解源程序】
    • 字节码【程序开发的过程中使用的就是这部分】
    • 帮助文档【对源码的解释说明被提取出来,更方便程序的开发】
      • javadoc.exe工具会将Java源文件中写的注释提取出来,生成帮助文档
  • package和import:
    • package(关键字)
      • 包又称为package,java中引用package这种语法机制,主要是为了方便程序的维护,不同功能的类被分门别类放到不同的软件包中,查找比较方便,管理比较方便,易维护
      • 怎么定义package呢?
        • 在Java源程序的第一行编写package语句
        • package只能编写一个语句
        • 语法结构:package 包名;
      • 包名的命名规范:
        • 公司域名倒序+项目名+模块名+功能名,采用这种方式重名的几率较低,因为公司域名具有全球唯一性
        • 包名要求全部小写
        • 包名也是标识符,必须遵守标识符的命名规则
      • 一个包对应一个目录
      • 使用了package机制之后应该怎么编译?怎么运行?
        • 使用了package之后,类名不在叫做Test01了,类名叫做:com.bjpowernode.javase.day11.Test01
        • 编译 javac Test01.java
        • 运行 java  com.bjpowernode.javase.day11.Test01(必须要将编译之后生成的字节码文件放到com.bjpowernode.javase.day11包下面才能运行)
        • 另一种方式(编译+运行)
        • 带包编译:javac -d 编译之后存放路径  java源文件的路径,eg:javac -d . *.java
    • import(关键字)
      • 在同一个包中,代码中写全类名的时候,包名可以省略,只写类名,也不需要import,但是不在同一个包中,必须写全类名,或者要import导入
        • import   java.util.Scanner;或者import   java.util.*;
      • import需要编写在package语句之下,class语句之上 
      • java.lang.*;不需要手动引入,Java系统自动引入
  • 访问控制权限修饰符:
    • 访问权限修饰符可以变量、方法、类/接口(只能采用public和缺省进行修饰【内部类除外】)
    • 访问权限修饰符包括:
      • public         表示公开,在任何位置都可以访问
      • protected    同包或其他包中的子类
      • 缺省            同包
      • private         表示私有的,只能在本类中访问
      • public>protected>缺省>private
  • System.exit(0);终止JVM运行
posted @ 2023-02-03 19:27  媛~~  阅读(36)  评论(0编辑  收藏  举报