Bootstrap

Java基础大纲

java基础常识

你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

概述

  1. java特点
    1)面向对象:看名字它是注重对象的。当解决一个问题的时候,面向对象会把事物抽象成对象的概念,就是说这个问题里面有哪些对象,然后给对象赋一些属性和方法,然后让每个对象去执行自己的方法,问题得到解决。(面向过程:从名字可以看出它是注重过程的。当解决一个问题的时候,面向过程会把事情拆分成: 一个个函数和数据(用于方法的参数) 。然后按照一定的顺序,执行完这些方法(每个方法看作一个过程),等方法执行完了,事情就搞定了。)
    例子

    2)平台移植性:java语言只要编写一次,可以做到到处运行。例如:java程序编写完之后,可以运行在windows操作系统上,不需要做任何改动可以直接运行在Linux操作系统上,同样也 可以运行到MaC OS上面。 一次编写,到处运行。(平台改变了,程序不需要改。) JVM(把程序代码翻译成对应程序可以理解的代码)这种机制实现了跨平台,那么这种机制优点和缺点分别是什么?
    优点:一次编写到处运行,可以跨平台。
    缺点:麻烦。对于运行java程序来说必须先有一个JVM。
    就像你要想在网页上看视频,你必须先安装一个flash是一样的。

    3)简单性,安全性:在Java语言当中真正操作内存的是:JVM(Java虚拟机) 所有的java程序都是运行在Java虚拟机当中的。 而Java虚拟机执行过程中再去操作内存。 对于C或者C++来说程序员都是可以直接通过指针操作内存的。 C或者C++更灵活,可以直接程序员操作内存,但是要求程序员技术精湛。C语言或者C++更有驾驭感。 Java语言屏蔽了指针概念,程序员不能直接操作指针,或者说程序员
    不能直接操作内存。这种方式有优点也有缺点:
    优点:不容易导致内存泄漏。(简单了。)
    缺点:效率问题,包括驾驭感比较差。

    4)多线程:java完全/完美支持多线程并发

    5)健壮性: 主要是因为Java中有一种机制: 自动垃圾回收机制(GC机制)。 java语言是健壮的,相对于C语言来说,C语言没有Java健壮。Java不容易导致内存的泄漏。 C++或者C语言使用不当时很容易导致内存泄漏。JVM负责调度GC机制。程序员不需要干涉。以上讲解中又描述了这几个术语:JVM(C++语言写的一个虚拟的计算机)、GC(垃圾回收机制)

  2. 术语
    1)jdk:Java开发工具箱
    2)jre:java运行环境
    3)jvm:java虚拟机

    JDK包括JRE,JRE包括JVM。JVM是不能独立安装的。JRE和JDK都是可以独立安装的。有单独的JDK安装包。也有单独的JRE安装包。 没有单独的JVM安装包。安装JDK的时候:JRE就自动安装了,同时JRE内部的JVM也就自动安装了。 安装JRE的时候:JVM也就自动安装了。

    问题:
    假设你在软件公司开发了一个新的软件,现在要去客户那边给客户把项目部署一下,把项目跑起来,你需要安装JDK吗?只需要安装JRE就行了。JRE体积很小,安装非常便捷快速。

    问题:
    为什么安装JDK的时候会自带一个JRE? 因为java程序员开发完程序之后,要测试这个程序,让这个程序运行起来,需要JRE。所以JDK安装的时候内部自带一个JRE。

  3. 大致执行过程
    java程序非常重要的两个阶段:
    编译阶段
    运行阶段

注意:java程序员直接编写的java代码(普通文本)是无法执行被JVM 识别的。java程序员编写的java代码这种普通文本必须经过一个编译,将这个“普通文本代码”变成“字节码”,JVM能够识别“字节码”。 java代码这种普通文本变成字节码的过程,被称为:编译。 java代码这种普通文本被称为:java源代码。(你编写的代码是源代码)源代码不能直接执行,需要先进行编译,生成源代码对应的“字节码”JVM可以识别的是字节码。

编译阶段和运行阶段可以在不同的操作系统上完成吗?
在windows上编译 编译之后生成了“字节码”,把“字节码”放到linux上运行,完全可以,因为Java是跨平台的。可以做到一次编写到处运行。

java源代码一旦编译之后,源代码可以删除吗?只留下字节码可以执行吗?
完全可以执行,因为源代码不参与程序的执行过程。 参与程序执行过程的是字节码。 但是最好不要删除源代码。因为有可能执行结果不是你需要的,当执行结果不是你需要的时候,你可以重新打开源代码进行修改,然后重新编译生成新的字节码,再重新执行。这样会有新的执行效果。

放源代码的文件扩展名必须是:xxx.java,并且需要注意的是:编译生成的字节码文件扩展名是:xxx.class
.java文件就是源文件,这个文件中编写源代码。.class文件就是字节码文件,这个文件是编译源代码而得到的。另外需要注意的是:1个java源文件是可以编译生成多个class文件的。 最终运行的是class文件。

问题:字节码文件是二进制文件吗?字节码文件不是二进制文件。 如果是二进制的话,就不需要JVM了。 因为操作系统可以直接执行二进制。 java程序从开发到最终运行经历了什么?
编译期:(可以在windows上)
第一步:在硬盘的某个位置(随意),新建一个xxx.java文件
第二步:使用记事本或者其它文本编辑器例如idea打开xxx.java文件
第三步:在xxx.java文件中编写“符合java语法规则的”源代码。
第四步:保存(一定要将xxx.java文件保存一下)
第五步:使用编译器(javac【JDK安装后自带】)对xxx.java文件进行编译。
第六步:如果xxx.java文件中编写的源代码是符合语法规则的,编译会通过,如果xxx.java文件中编写的源代码违背了语法规则,那么编译器会报错,编译器 报错之后class文件是不会生成的,只有编译通过了才会生成class字节码文件。并且一个java源文件是可以生成多个class文件的。(编译实质上是检查语法)

运行期(JRE在起作用):(可以在windows上,也可以在其他的OS上。)
第七步:如果是在Linux上运行,需要将windows上生成的class文件拷贝过去 不需要拷贝源代码,真正运行的是字节码。(但是源代码也不要删除,有用)
第八步:使用JDK自带的一个命令/工具:java(负责运行的命令/工具)执行字节码
第九步:往下的步骤就全部交给JVM了,就不需要程序员干涉了。JVM会将字节码文件装载进去,然后JVM对字节码进行解释(解释器负责将字节码解释为1010101010…等的二进制)
第十步:JVM会将生成的二进制码交给OS操作系统,操作系统会执行二进制码和硬件进行交互。

注意:在以上的过程中,需要使用两个非常重要的命令?
javac 命令,负责编译
java 命令,负责运行

小插曲:
xxx.java源文件经过编译之后生成了A.class、B.class、C.class等文件, 那么我们称A是一个类、B是一个类、C是一个类。其中A、B、C是类的名字。 没有为什么,死记硬背,SUN公司的java语法就是这么规定的。 A/B/C是类的名称。A类、B类、C类。源文件中编写的代码叫做:源代码。以上是一个复杂的过程,那么缩减一下,程序员到底要干啥?
新建java文件
打开java文件
写java源代码
保存
javac命令编译
java命令运行
编写、编译、运行

  1. Java可以干什么:
    网站后台开发
    Android APP 开发
    大数据开发
    客户端程序(PC 程序)开发
    嵌入式开发

基本语法

1.关键字
在SUN公司开发Java语言的时候,提前定义好了一些具有特殊含义的单词,这些单词全部小写,具有特殊含义,不能用作标识符。java语言中的所有关键字都是全部小写。 注意:java语言中是严格区分大小写的。public和Public不一样。 Class和class不一样。static和Static也不一样。

2.标识符
标识符可以标识什么?
类名、接口名
变量名、方法名
常量名

标识符的命名规则?
标识符只能由数字 字母(可以有中文) 下划线 美元符号组成,不能有其它符号。 标识符不能以数字开始, 标识符严格区分大小写, 关键字不能做标识符, 理论上没有长度限制

标识符的命名规范?
见名知意

驼峰命名方式,一高一低
类名、接口名:首字母大写,后面每个单词首字母大写。
变量名、方法名:首字母小写,后面每个单词首字母大写。
常量名:全部大写,每个单词之间使用下划线衔接。

3.变量
1)字面量就是数据, 数据就是字面量,是一个东西。

2)变量的三要素? 数据类型、变量名、值 (值就是数据,就是字面量。) int i = 100;
到底什么叫做同一个域?????
这个目前不太好解释,大家记住吧:一个大括号代表一个域。
{A域
{B域
{C域
}
}
}
A域包括B域,B域包括C域。

在方法体当中声明的变量叫做局部变量,在方法体外以及类体内声明的变量叫做成员变量。

变量的作用域
出了大括号就不认识了。别的先别管。
{
int i = 100;
{
在这里可以访问i
}
}
{
在这里是无法访问i变量。
}

数据类型

1.数据类型有什么用?
数据类型用来声明变量,程序在运行过程中根据不同的数据类型分配不同大小的空间。
int i = 10;
double d = 1.23;
i变量和d变量类型不同,空间大小不同。

1.2、数据类型在java语言中包括两种:
第一种:基本数据类型
基本数据类型又可以划分为4大类8小种:
第一类:整数型
byte,short,int,long (没有小数的)
第二类:浮点型
float,double (带有小数的)
第三类:布尔型
boolean:只有两个值true和false,true表示真,false表示假
第四类:字符型
char:java中规定字符型字面量必须使用单引号括起来。属于文字。
8小种:
byte,short,int,long
float,double
boolean
char

第二种:引用数据类型
字符串型String属于引用数据类型。
String字符串不属于基本数据类型范畴。
java中除了基本数据类型之外,剩下的都是引用数据类型。
类型 占用字节数量(byte)
------------------------------------
byte 1
short 2
int 4
long 8
float 4
double 8
boolean 1 (1byte的1或0,00000001(true)或00000000(false))
char 2

在类型转换的时候需要遵循哪些规则?
第一条:八种基本数据类型中,除 boolean 类型不能转换,剩下七种类型之间都可以 进行转换;
第二条:如果整数型字面量没有超出 byte,short,char 的取值范围,可以直接将其赋值给byte,short,char 类型的变量;
第三条:小容量向大容量转换称为自动类型转换,容量从小到大的排序为:
byte < short(char) < int < long < float < double,其中 short和 char 都占用两个字节,但是char 可以表示更大的正整数;
第四条:大容量转换成小容量,称为强制类型转换,编写时必须添加“强制类型转换符”, 但运行时可能出现精度损失,谨慎使用;
第五条:byte,short,char 类型混合运算时,先各自转换成 int 类型再做运算;
第六条:多种数据类型混合运算,各自先转换成容量最大的那一种再做运算;

控制语句

控制语句包括几类? 3类: 选择语句 循环语句 转向语句

1)选择语句也可以叫做分支语句
if语句
switch语句

2)循环语句:主要循环反复的去执行某段特定的代码块
for循环
while循环
do…while…循环

3)转向语句
break
continue
return

方法

1)方法是一段可以完成某个特定功能的并且可以被重复利用的代码片段。 方法的出现,让代码具有了很强的复用性。

2)方法重载overload,什么情况下我们考虑使用方法重载机制? 当功能相似的时候,建议将方法名定义为一致的,这样代码美观,又方便编程。 注意:如果功能不相似,坚决要让方法名不一致。代码满足什么条件的时候构成了方法重载? 条件1:在同一个类当中 条件2:方法名相同,条件3:形式参数列表不同(类型、个数、顺序)

3)方法递归、需要理解什么是方法递归? 方法自身调用自身。使用递归的时候,必须添加结束条件,没有结束条件,会发生栈内存溢出错误。StackOverflowError 原因:一直压栈,没有弹栈,栈内存不够用。

面向对象

1.封装,继承,多态
1)封装的代码实现两步:
第一步:属性私有化
第二步:1个属性对外提供两个set和get方法。外部程序只能通过set方法修改,只能通过get方法读取,可以在set方法中设立关卡来保证数据的安全性。在强调一下:set和get方法都是实例方法,不能带static。不带static的方法称为实例方法,实例方法的调用必须先new对象。set和get方法写的时候有严格的规范要求:(大家要按照规矩来)
set方法长这个样子:
public void set+属性名首字母大写(1个参数){
xxx = 1个参数;
}
get方法长这个样子:
public 返回值类型 get+属性名首字母大写(无参){
return xxx;
}
static关键字,static修饰的统一都是静态的,都是类相关的,不需要new对象。直接采用“类名.”访问。当一个属性是类级别的属性,所有对象的这个属性的值是一样的,建议定义为静态变量。
this是一个关键字,是一个引用,保存内存地址指向自身。this可以使用在实例方法中,也可以使用在构造方法中。this出现在实例方法中其实代表的是当前对象。this不能使用在静态方法中。this. 大部分情况下可以省略,但是用来区分局部变量和实例变量的时候不能省略。this() 这种语法只能出现在构造方法第一行,表示当前构造方法调用本类其他的 构造方法,目的是代码复用。
2)继承
继承:在现实世界当中也是存在的,例如:父亲很有钱,儿子不用努力也很有钱。
继承的作用:基本作用:子类继承父类,代码可以得到复用。(这个不是重要的作用,是基本作用。)主要(重要)作用:因为有了继承关系,才有了后期的方法覆盖和多态机制。
java 中的继承只支持单继承,不支持多继承,C++中支持多继承,虽然 java 中不支持多继承,但有的时候会产生间接继承的效果,例如:class C extends B,class B extends A,也就是说,C 直接继承 B,其实 C 还间接继承 A。java 中规定,子类继承父类,除构造方法不能继承之外,剩下都可以继承。但是私有的属性无法在子类中直接访问。(父类中private修饰的不能在子类中 直接访问。可以通过间接的手段来访问。)java 中的类没有显示的继承任何类,则默认继承 Object类,Object类是 java 语言提供的根类(老祖宗类),也就是说,一个对象与生俱来就有Object类型中所有的特征。
方法覆盖
什么时候考虑使用方法覆盖?
父类中的方法无法满足子类的业务需求,子类有必要对继承过来的方法进行覆盖。什么条件满足的时候构成方法覆盖?
第一:有继承关系的两个类
第二:具有相同方法名、返回值类型、形式参数列表
第三:访问权限不能更低。
第四:抛出异常不能更多。
关于Object类中toString()方法的覆盖?
toString()方法存在的作用就是:将java对象转换成字符串形式。大多数的java类toString()方法都是需要覆盖的。因为Object类中提供的toString()方法输出的是一个java对象的内存地址。 至于toString()方法具体怎么进行覆盖? 格式可以自己定义,或者听需求的。(听项目要求的。)
方法重载和方法覆盖有什么区别?
方法重载发生在同一个类当中。方法覆盖是发生在具有继承关系的父子类之间。 方法重载是一个类中,方法名相同,参数列表不同。方法覆盖是具有继承关系的父子类,并且重写之后的方法必须和之前的方法一致:方法名一致、参数列表一致、返回值类型一致。
3)多态
向上转型和向下转型的概念。
向上转型:子—>父 (upcasting)又被称为自动类型转换:Animal a = new Cat();
向下转型:父—>子 (downcasting)又被称为强制类型转换:Cat c = (Cat)a; 需要添加强制类型转换符。
什么时候需要向下转型?需要调用或者执行子类对象中特有的方法。必须进行向下转型,才可以调用。
向下转型有风险吗? 容易出现ClassCastException(类型转换异常)
怎么避免这个风险?instanceof运算符,可以在程序运行阶段动态的判断某个引用指向的对象 是否为某一种类型。养成好习惯,向下转型之前一定要使用instanceof运算符进行判断。不管是向上转型还是向下转型,首先他们之间必须有继承关系,这样编译器就不会报错。
什么是多态。多种形态,多种状态,编译和运行有两个不同的状态。 编译期叫做静态绑定。 运行期叫做动态绑定,Animal a = new Cat();
// 编译的时候编译器发现a的类型是Animal,所以编译器会去Animal类中找move()方法
// 找到了

;