- JAVA入门
- JAVA三大版本
- JAVA的特性和优势
- JAVA运行机制
- JVM、JRE、JDK
- JAVA开发环境搭建
- 变量、数据类型和运算符
- 变量(variable)
- 变量的本质
- 变量的声明
- 变量的分类和作用域
- 局部变量
- 成员变量(也叫实例变量)
- 静态变量(又叫类变量)
- 常量(Constant)
- 基本数据类型
- 整型
- byte
- short
- int
- long
- 整型的不同进制表示方式
- 浮点型
- float
- double
- 字符型
- char
- 常用转义字符
- 布尔型(boolean)
- 运算符
- 算术运算符
- 赋值及其扩展赋值运算符
- 关系运算符
- 逻辑运算符
- 位运算符
- 字符串连接符
- 条件运算符
- 运算符优先级的问题
- 数据类型的转换
- 自动类型转换
- 强制类型转换
- IDEA的使用
- 下载和安装IDEA
- IDEA的配置和使用
- IDEA超好用快捷键介绍
- 控制语句
- IF
- if单分支结构
- if-else双分支结构
- if-else if-else 多分支结构
- SWITCH结构
- break和continue
- 嵌套循环
- 递归结构
- 方法
- 面向对象概念
- 初识面向对象
- 引入表格和类的比较
- 类的方法和表格中的动作
- 对象对应表格中的行数据
- 面向过程和面向对象
- 面向过程和面向对象的区别
- **面向对象和面向过程思想的总结**
- 对象和类的详解
- 类的定义
- 属性(field)
- **方法(method)**
- 构造方法(构造器constructor)
- 面向对象的内存分析
- 栈(stack)
- 堆(heap)
- 方法区(method area)
- 垃圾回收机制(Garbage Collection)
- 垃圾回收原理
- 垃圾回收算法
- 引用计数法
- 引用可达法(根搜索算法)
- 分代回收垃圾机制
- 包机制(package和import)
- 继承
- 封装
- 多态
- Object类详解
- Object类基本特性
- toString()方法
- “==”和equals方法比较
- super关键字
- 抽象类
- 接口interface
- 字符串String类
- 内部类
- 数组
- 数组的概念
- 数组常见操作
- 多维数组
- 常见算法
- JavaSE(Java Standard Edition):标准版,在个人计算机上使用。
JavaSE是Java平台的核心,它提供了非常丰富的API来开发一般个人计算机上的应用程序。
- JavaEE(Java Enterprise Edition):企业版,定位在服务器端的应用。
JavaEE是JavaSE的扩展,增加了用于服务器开发的类库。
- JavaME(Java Micro Edition):微型版,定位在消费性电子产品应用上。
JavaME是JavaSE的内申,包含J2SE的一部分核心类,也有自己的扩展类,增加了适合微小装置的类库。该版本针对资源有限的电子消费产品的需求精简核心库,并提供了模块化的架构让不同产品随时能增加支持的能力。
安卓开发属于JavaME,但不要认为JavaME就是安卓开发,安卓开发只是JavaME其中的一部分。
JAVA的特性和优势-
跨平台/可移植性
这是Java的核心优势。比如Java的int类型永远是32位,不像C/C++可能是16或32位,根据编译器厂商规定来变化。这样Java程序的移植就会很方便。
-
安全性
Java适合网络/分布式环境,为了达到这个目标,在安全性方面投入了很大的精力,使Java可以很容易构建防病毒,防篡改的系统。
-
面向对象
与C++相比,Java是完全面向对象的语言。
-
简单性
Java就是C++的简化版,也可以把Java称之为“C+±”,指的就是将C++的一些内容去掉,比如头文件、指针、结构、联合、操作符重载、虚基类等等。同时,Java的语法是基于C语言的,学习成本会很低。
-
高性能
Java在最初发展阶段性能较低,这在高级语言中往往是难以避免的,Java语言通过虚拟机的优化可以提升几十倍的运行效率。这样Java程序的执行效率就会大大提高。
-
分布式
Java是为Internet的分布式环境设计的,因为它能够处理TCP/IP协议。
-
多线程
多线程的使用可以带来更好的交互响应和实时行为。
-
健壮性
Java是一种健壮性的语言,它吸收了C/C++的优点,但去掉了影响程序健壮性的部分(如:指针,内存的申请和释放等)。Java程序不会造成计算机崩溃。及时Java程序出错时会把异常抛出,在通过异常处理机制加以处理。
- Java首先用文本编辑器编写Java源程序,源文件的后缀名为.java;
- 再利用编译器(javac)将源程序编译成字节码文件,字节码文件的后缀名为.class;
- 最后利用虚拟机(解释器,java)解释执行。如上图所示。
计算机高级语言主要类型有编译型和解释型两种,而Java是两种类型的结合。
JVM、JRE、JDK-
JVM(Java Virtual Machine):Java虚拟机,用于执行字节码的“虚拟计算机”。
不同操作系统上有不同版本的JVM,屏蔽了底层运行平台的差异,是实现跨平台的核心。
-
JRE(Java Runtime Environment):包含JVM,库函数等。
-
JDK(Java Development kit):包含JRE,编译器和调试器等。
-
下载JDK
https://www.oracle.com/java/technologies/downloads/
-
安装JDK
选择JDk安装目录,采用默认即可。(如果自定义目录,注意路径中不能包含中文)
- 变量是一个可操作的内存空间,空间位置是确定的,但里面当放的值不确定。
- 可通过变量名来访问对应的存储空间,从而操作这个空间存储的值。
- Java是一种强类型语言,每个变量都必须声明其数据类型。变量的数据类型决定了变量所占存储空间的大小。
double salary; int age; long earth_moon_distance;
声明变量的初始化,这一点和C语言相同
int age = 18; double e = 2.717271828; int i,j; //同时定义两个变量,都是int类型变量的分类和作用域
变量有三种类型:局部变量、成员变量(实例变量)和静态变量。
局部变量方法或语句块内部定义的变量。生命周期从声明位置开始到方法或语句块执行完毕为止。局部变量在使用前必须先声明和初始化后再使用。
public void test(){
int i;
int j = i+1;//编译会出错,变量i未初始化
}
public void test(){
int i = 1;
int j = i+1;//编译正确
}
成员变量(也叫实例变量)
方法外部、类内部定义的变量。从属于对象,生命周期伴随对象始终。可以不自行初始化,系统会自动初始化为对应类型的默认值。
public class Test{
int age; //int类型,默认初始化为0
double score; //double类型:默认初始化为0.0
char ch; //char类型:默认初始化为:'u0000'(前缀u是指Unicode编码表示)
boolean flag; //boolean类型:默认初始化为false
}
静态变量(又叫类变量)
使用static定义。从属于类,生命周期伴随类始终,从类加载到卸载。如果不自行初始化,与成员变量一样会自动初始化为对应类型的默认值。
常量(Constant)在Java语言中,用关键字final来定义一个常量。
声明格式:
| final 类型 变量名 = 初始化值; |
|---|
public class TestConstant{
public static void main(String[ ] args){
final double PI = 3.14;
PI = 3.15; //编译错误!final修饰不能再被赋值
}
}
基本数据类型
整型
byte
1字节 表述范围:-2(7) ~ 2(7)-1 (-128~127)
short2字节 表述范围:2(15) ~ 2(15) -1 (-32768~32767)
int4字节 表述范围:-2(31) ~ 2(31)-1 (-2147483648~2147483647) 约21 亿
long8字节 表述范围:-2(63) ~ 2(63)-1
Java中整型默认为int型,声明long型常量可以在后面加 ’ l ’ 或 ’ L ’ 。
long a = 10000000; //编译通过,因为在int表示范围内(21亿)。 long b = 10000000000; //编译错误(报错:The literal 10000000000 of type int is out of range),因为会把右边的数默认为int型,但超出int表示范围。必须在后面加上L long c = 10000000000l //编译通过。整型的不同进制表示方式
- 十进制整数,如:99,-100,0
- 八进制整数,以0开头,如:015
- 十六进制整数,以0x开头,如:0x15
- 二进制数,以0b开头,如:0b01100101
4字节 表述范围:-3.403E38~3.403E38
double8字节 表述范围:-1.798E308~1.798E308
浮点型常量默认是double,要改成float可以在后面加f或F。
通常不要比较两个浮点数的值,因为浮点数不够精确。
【示例 1】浮点型数据的比较一
float f = 0.1f; double d = 1.0/10; System.out.println(f==d); //结果为false
【示例 2】浮点型数据的比较二
float d1 = 123456789f;
float d2 = d1+1;
if(d1==d2)
System.out.println("d1=d2");
else
System.out.println("d1!=d2");
//输出结果为d1=d2,说明浮点数的精度是有限的,即使d1加1也被忽略掉了。
所以,不要使用浮点数进行比较!需要比较可以使用BigDecimal类
java.math包下面有两个类:BigInteger和BigDecimal,这两个类可以处理任意长度的数值。BigInteger实现了任意精度的整数运算。BigDecimal实现了任意精度的浮点数运算。
字符型 char2字节 在Java中使用单引号来表示字符常量。例如:‘A’,它与**“A”**是不同的。
char类型用来表示Unicode编码表中的字符。Unicode编码被设计用来处理各种语言的文字,它占2个字节,可允许有65536个字符。所以也可以用中文表示一个char类型字符。
char c1 = 'a'; char c2 = '中'; //汉字“中”和“a”的地位相同。常用转义字符
char c1 = 'n'; //换行 char c2 = 'b'; //退格 char c3 = 'r'; //回车 char c4 = 't'; //制表符 char c5 = '“'; //双引号 char c6 = '\'; //反斜杠布尔型(boolean)
- boolean类型有两个常量值,true和false。
- 占1个或4个字节,不能使用0或非0的整数代替true和false,这点和C语言不同。
JVM把单独一个boolean当做int来处理,所以占4字节,把boolean数组当byte处理,占1字节。所以,boolean类型单独使用时占4字节,在数组中时占1字节。
运算符 算术运算符- +,-,*,/,%属于二元运算符。%是取模运算符,就是我们常说的求余数操作。
- 算术运算符中++(自增),–(自减)属于一元运算符。
二元运算符的运算规则:
整数运算:
-
如果两个操作数有一个为 long, 则结果也为 long。
-
没有 long 时,结果为 int。即使操作数全为 short,byte,结果也是int。
浮点运算:
-
如果两个操作数有一个为 double,则结果为 double。
-
只有两个操作数都是 float,则结果才为 float。
取模运算:
- 其操作数可以为浮点数,一般使用整数,结果是“余数”,“余数”符号和左边操作数相同,如:7%3=1,-7%3=-1,7%-3=1。
| += | a+=b | a = a+b |
|---|---|---|
| -= | a-=b | a = a-b |
| *= | a*=b | a = a*b |
| /= | a/=b | a = a/b |
| %= | a%=b | a = a%b |
关系运算符用来进行比较运算。关系运算的结果是布尔值:true/false;
- =是赋值运算符,而真正的判断两个操作数是否相等的运算符是==。
- ==、!= 是所有(基本和引用)数据类型都可以使用。
- > 、>=、 <、 <= 仅针对数值类型
逻辑运算的操作数和运算结果都是 boolean 值。
| 与 | & | 只要有一个为 false,则 false |
|---|---|---|
| 短路与 | && | 只要有一个为 false,则 false |
| 或 | | | 只要有一个为 true, 则 true |
| 短路或 | || | 只要有一个为 true, 则 true |
| 非 | ! | 取反 |
| 异或 | ^ | 相同为 false,不同为 true |
位运算指的是进行二进制位的运算。
| ~ | 取反 |
|---|---|
| & | 按位与 |
| | | 按位或 |
| ^ | 按位异或 |
| << | 左移运算符,左移 1 位相当于乘 2 |
| >> | 右移运算符,右移 1 位相当于除 2 取商 |
&和|既是逻辑运算符,也是位运算符。如果两侧操作数都是 boolean 类型,就作为逻辑运算符。如果两侧的操作数是整数类型,就是位运算符。
字符串连接符“+”运算符两侧的操作数中只要有一个是字符串(String)类型,系统会自动将另一个操作数转换为字符串然后再进行连接。
int a = 10;
System.out.println("a="+12); //输出结果为:a=10
条件运算符
| x?y:z |
|---|
运算符的优先级
| 优先级 | 运算符 | 类 |
|---|---|---|
| 1 | () | 括号运算符 |
| 2 | !、+(正号)、-(负号) | 一元运算符 |
| 2 | ~ | 位逻辑运算符 |
| 2 | ++、– | 递增与递减运算 |
| 3 | *、/、% | 算术运算符 |
| 4 | +、- | 算术运算符 |
| 5 | <<、>> | 位左移、右移运算符 |
| 6 | >、>=、<、<= | 关系运算符 |
| 7 | ==、!= | 关系运算符 |
| 8 | & | 位运算符、逻辑运算符 |
| 9 | ^ | 位运算符、逻辑运算符 |
| 10 | | | 位运算符、逻辑运算符 |
| 11 | && | 逻辑运算符 |
| 12 | || | 逻辑运算符 |
| 13 | ? : | 条件运算符 |
| 14 | =、+=、-=、*=、/=、%= | 赋值运算符、扩展运算符 |
容量小的数据类型可以自动转换为容量大的数据类型
比如:int转为long、short转为int、char转为int等,所有基本数据类型都可以转为double,但转换时可能会有精度的损失。
强制类型转换double a = 3.91; int x = (int)a; //将a强转为int型,但损失了小数后的数据
注意:
强转时如果超出范围,就会被截断成一个错误的值!
int x = 300; byte b = (byte)x; //byte的范围是-128~127,x的值超过强转类型的范围 //输出结果 b = 44,是一个错误的值。IDEA的使用 下载和安装IDEA
下载地址: https://www.jetbrains.com/idea/download/#section=windows
IDEA的配置和使用在IDEA中创建Java项目
点击“Create New Project”,创建新的项目。
- 选择 JD
- 根据项目模板创建项目
- 填写项目名称和包名
- 开始编写代码
语法结构:
if(布尔表达式){
语句块
}
if-else双分支结构语法结构:
if(布尔表达式)
{ 语句块 1 }
else
{ 语句块 2 }
if-else if-else 多分支结构语法结构:
if(布尔表达式 1)
{ 语句块 1; }
else if(布尔表达式 2)
{ 语句块 2; }……
else if(布尔表达式 n)
{ 语句块 n; }
else
{ 语句块 n+1; }
SWITCH结构switch多分支结构(多值情况)
语法结构:
switch(表达式){
case 值1:
语句块1;
break;
case 值2:
语句块2;
break;
... ... ...
default:
默认语句块;
}
- switch会根据表达式的值从相匹配的case处开始执行,一直执行到break处或者是switch的末尾。如果表达式的值没有与任何一个case值匹配,则执行default语句。
- switch中表达式的值,可以int(byte、short、char)、枚举、字符串(JDK7 新特性)。
public class TestSwitch{
public static void main(String[] args){
int month = 0;
//用switch实现上述if多分支语句
switch(month){
case 1:
case 2:
case 3:
System.out.println("春季");
break;
case 4:
case 5:
case 6:
System.out.println("夏季");
break;
case 7:
case 8:
case 9:
System.out.println("秋季");
break;
case 10:
case 11:
case 12:
System.out.println("冬季");
break;
default:
System.out.println("月份信息错误!");
}
}
}
break和continue
- break用于强制退出整个循环
- continue用于结束本次循环,继续执行下一次循环。
while(true){
System.out.println("请输入您的月薪:");
int month_salary = scanner.nextInt(); //从键盘上读取月薪
System.out.println("请输入每年的薪资月数:");
int months = scanner.nextInt(); //从键盘读取月份数
System.out.println("按任意键获得年薪结果--------");
System.out.println("输入exit可退出程序---------");
System.out.println("输入next可以重新输入--------");//打印提示信息
scanner.nextLine();
String command = scanner.nextLine(); //获取用户下一步的操作指令
switch(command){//用switch实现多分支语句
case "exit":
break;
case "next":
continue;
default:
System.out.println("您的年薪是:"+month_salary*months);
}
}
嵌套循环
public class Test{
public static void main(String[] args){
for(int i=1;i<=9;i++){
for(int j=1;j<=i;j++){
System.out.print(j+"*"+i+"="j*i+"t");
}
System.out.println();
}
}
}
递归结构
递归的思想:自己调用自己。
递归结构包括两部分:
- 定义递归头 递归头就是递归的结束条件。没有递归头递归将会陷入死循环。
- 递归体 调用自身的方法
//利用递归求阶乘
static long factorial(int n){
if(n==1){//递归头
return 1;
}
else{//递归体
return n*factorial(n-1);
}
}
递归的缺陷:
算法简单是递归的优点。但是递归会调用大量的系统堆栈,导致内存消耗多,在递归层次较多时速度明显比循环慢,所以使用递归需要慎重。
方法介绍方法前,先讲语句块。语句块就是复合语句,一个语句块需要用**{}**包起来。
语句块内定义的变量是局部变量,只能在块内使用,不能在块外使用。当然,在语句块内也可以使用语句块外的全局变量。
方法:
Java中的方法相当于C语言的函数。
- 方法用于定义该类或该类的实例的行为特征和功能实现。
- 面向过程中,函数是最基本的单位,整个程序由一个个的函数调用组成。
- 面向对象中,类是最基本的单位,方法是从属于类和对象的。
方法的声明和定义也和C语言相同,方法也可以重载,可以参照C语言的规则。
面向对象概念 初识面向对象 引入表格和类的比较想必我们对表格再熟悉不过了,实际上,**“表格思维”**就是一种典型的面向对象思维。
在本质上,互联网上的数据都是用“表格”实现的,下面以公司雇员为例,下面介绍一下怎么由表格到类的。
| ID | 姓名 | 岗位 | 基本工资 | 绩效工资 | 入职日期 |
|---|---|---|---|---|---|
| 1001 | 张三 | 程序员 | 15000 | 6000 | 9/10 |
| 1002 | 李四 | 销售 | 12000 | 8000 | 8/21 |
| 1003 | 王五 | 财物 | 12000 | 0 | 11/20 |
| 1004 | 赵六 | 经理 | 20000 | 10000 | 3/19 |
上面这个雇员表,可以把公司的员工信息**“结构化”,“标准化”**,让管理者可以更方便的进行管理。
我们把表中的列叫做 “字段” ,英文叫 “filed” 。显然,一个表格的结构是有多个field构成的。
在面向对象中,类与表格的结构很相似,我们定义一个 “雇员类” ,类中的属性就是 “字段” ,一个类的实例叫 “对象” ,对应表格中的一行信息。
类的方法和表格中的动作在现实中,公司中的每个雇员都会集体参加一些动作,这些动作有:
- 开会
- 午休
- 提交工作日志
这些动作对应在类中就是方法。
对象对应表格中的行数据- 表结构对应:类结构
- 一行数据对应:一个对象
- 表中所有行数据对应:这个类的所有对象
面向过程重点关注如何执行,面向过程时,首先思考 “ 怎么按步骤实现?” ,并将步骤对应成方法,按步骤,一步步完成这些方法。
面向对象(Oriented-Object)的思维更契合人的思维模式。首先思考 “ 怎么设计这个事物?” ,因此,面向对象可以帮助我们从宏观上把握、从整体上分析整个系统。 但是,具体到 实现部分的微观操作(就是一个个方法),仍然需要面向过程的思路去处理。
面向对象和面向过程思想的总结- 都是解决问题的思维方式,都是代码组织的方式。
- 面向过程是一种“执行者思维”,解决简单问题可以使用面向过程。
- 面向对象是一种“设计者思维”,解决复杂、需要协作的问题可以使用面向对象。
- 面向对象离不开面向过程:
- 宏观上:通过面向对象进行整体设计
- 微观上:执行和处理数据,仍然是面向过程。
//每个源文件必须有且只有一个public class,并且类名和文件名保持一致!
public class Car{
...
}
//一个java文件可以同时定义多个class,但只能有一个public class
class Tyre{
...
}
class Engine{
...
}
class Seat{
...
}
对一个类来说,有三种成员:
- 属性field
- 方法method
- 构造器constructor
属性用于定义该类的对象包含哪些数据或者静态特征。定义成员变量时可以不必初始化,Java将会用默认值对其初始化。
属性定义格式:
| 【修饰符】 类型 属性名 【= 初始值】; |
|---|
方法用于定义该类的行为特行和功能实现。
方法定义格式:
| 【修饰符】 方法返回值类型 方法名(形参列表){方法体} |
|---|
构造器用于对象的初始化,而不是创建一个对象!
声明格式:
| 【修饰符】 类名(【形参列表】){…} |
|---|
构造器的四个要点:
- 构造器通过new关键字调用
- 构造器不能定义返回值类型,不能在构造器中使用return语句
- 如果没有手动定义构造器,系统会默认调用一个无参构造器。
- 构造器的方法名就是类名!
Java虚拟机的内存可以分为三个区域:栈stack、堆heap、方法区method area。
虚拟机栈(简称“栈”)的特点如下:
- 栈描述的是方法执行的内存模型。每个方法被调用后都会在栈中创建一个栈帧(存储局部变量、操作数、方法出口等)。
- JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等)。
- 栈属于线程私有,不能实现线程间共享。
- 栈的存储特性是 “先进后出,后进先出” 。
- 栈是由系统自动分配的,速度快,是一段连续的内存空间。
堆的特点如下:
- 堆用于存储创建好的对象或数组。(数组也是对象)
- JVM只有一个堆,被所有线程共享。
- 堆是不连续的内存空间,分配灵活,速度慢。
- 堆被所有线程共享,在堆上的区域,被划分为新生代、老年代,以方便内存回收。
方法区(也是堆)特点如下:
-
方法区根据JAVA虚拟机的规范,有不同的实现。
JDK7以前是“永久代“
JDK7部分去除“永久代”,静态变量、字符串常量池都挪到了堆内存中
JDK8是“元数据空间”和堆结合起来
-
JVM只有一个方法区,被所有线程共享。
-
方法区实际也是堆,用于存储类、常量相关的信息。
-
存放程序中一些永远不变的信息或唯一的内容。
-
常量池主要存放常量:如文本字符串、final常量值。
【示例 】编写 Person 类并分析内存
public class Person{
String name;
int age;
public void show(){
System.out.println(name);
}
public static void main(String[] args){
//创建p1对象
Person p1 = new Person();
p1.age = 23;
p1.name = "张三";
p1.show();
//创建p2对象
Person p2 = new Person();
p2.age = 25;
p2.name = "李四";
p2.show();
Person p3 = p1;
Person p4 = p2;
p4.age = 80;
System.out.println(p1.age);
}
}
运行时的内存分配图:
垃圾回收机制(Garbage Collection) 垃圾回收原理-
内存管理
Java的内存管理很大程度上就是:堆中对象的管理,包括对象空间的分配和释放。
-
对象空间的分配:使用new关键字创建对象后,会在堆中分配一块内存空间。
-
对象空间的释放:将对象赋值null即可。
-
-
垃圾回收过程
- 发现无用对象
- 回收内存
当一个对象没有被任何变量引用时,该对象就成了无用对象。Java通过垃圾回收算法来发现并回收无用对象。
堆中的每个对象都对应一个引用计数器,当有引用指向这个对象时,引用计数器的值加1,而当指向该对象的引用失效时,引用计数器的值减1。当引用计数器减为0时,Java的垃圾回收器就认为该对象是无用对象,对其进行回收。
优点是算法简单,缺点是当出现两个对象互相引用时,即出现“循环引用的无用对象”,该算法就无法识别其为无用对象。
引用可达法(根搜索算法)把所有的引用关系看做一张图,从一个节点 GC ROOT 开始,寻找对应的引用 节点,找到这个节点以后,继续寻找这个节点的引用节点,当所有的引用节点寻找 完毕之后,剩余的节点则被认为是没有被引用到的节点,即无用的节点。
分代回收垃圾机制分代垃圾回收机制,基于这样一个事实:不同对象的生命周期不一样。因此,不同生命周期的对象可以采用不同的回收算法。将对象分为三种状态:年轻代、年老代、永久代。同时,处于不同状态的对象放到堆中的不同的区域。
包机制(package和import) 继承 封装 多态 Object类详解 Object类基本特性 toString()方法 “==”和equals方法比较 super关键字 抽象类 接口interface 字符串String类 内部类 数组 数组的概念 数组常见操作 多维数组 常见算法


