初识 Java
Java 发展史
Java的诞生
1995年5月23日,在Sun World大会上,Java第一次公开发布。
JDK1.0的发布
1996年1月,Sun 发布了JDK 1.0,它包括两个部分,运行环境(JRE)和开发环境(JDK)。
Java 2 问世
1998年12月,JDK 1.2 问世,并开始使用”Java 2“ 这一名称。
Java 2 平台包括:
- 标准版(J2SE)
- 企业版(J2EE)
- 微缩版(J2ME)
Java的特性
- 面向对象
- 平台无关
Java虚拟机(JVM)
Java虚拟机(Java Virtual Machine, JVM)不是一台真是的机器,而是想像中的机器,通过模拟真是机器来运行Java程序。
Java程序的工作原理
垃圾回收机制
Java虚拟机提供了一个系统级线程(垃圾回收器线程),它自动跟踪每块被分配出去的内存,自动释放被定义成垃圾的内存。
程序员可以调用System.gc()这个方法通知Java虚拟机释放无用资源,但Java虚拟机会选择在合适的时候释放无用资源,具体释放的时间不是程序员调用System.gc()的时刻,而是由Java虚拟机决定的,程序员不能精确控制和干预。
JDK 的结构
JDK是一个Java应用程序的开发环。它包括两部分,下层是处于操作系统层之上的运行环境,上层由编译工具、调试工具和运行Java程序所需的工具组成。
JDK主要包含以下基本工具(仅列举部分常用工具):
javac:编译器,江源程序转成字节码文件。
java:执行器,运行编译后的字节码文件。
javadoc:文档生成器,从源码注释中自动生成java文档。
jar:打包工具,将相关的类文件打包成一个文件。
JDK常用类库:
java.lang:系统基础类库,其中包括字符串类等。
java.io:输入/输出类库,例如进行文件读/写需要用到。
java.net:网络相关类库,例如进行网络通信会用到其中的类。
java.util:系统辅助类库,编程中经常用到的集合属于这个类库。
java.sql:数据库操作类库,连接数据库、执行SQL语句、返回结果及需要用到该类库。
javax.servlet:JSP、Servlet等使用到的类库,是java后台技术的核心类库。
配置 JDK 环境变量
变量名 | 说明 | 举例 |
---|---|---|
JAVA_HOME | JDK的安装路径 | C:\jdk1.6 |
PATH | Windows 系统执行命令时需要搜索的路径 | %JAVA_HOME%\bin; |
CLASSPATH | 编译和运行时要找的class路径 | .;%JAVA_HOME%\lib(其中 . 代表当前路径) |
第一个java程序
public class HelloWorld{
public static void main(String[] args){
System.out.println("Hello world!")
}
}
Java 程序简述
编写java类的注意事项:
- Java源文件以java为拓展名。
- 文件的基本组成部分是类(class)。
- 一个源文件中最多只能有一个public类,且如果有public类,源文件必须以public类名命名。
注释
类型 | 描述 |
---|---|
单行注释 | // 注释一行 |
多行注释 | /* …… */ 注释多行 |
文档注释 | /** …… */ 注释多行,并写入 javadoc 文档 |
数据类型和运算符
标识符和关键字
Java 对各种变量、方法和类等要素命名时使用的字符序列称为标识符。
标识符的命名规则
(1)标识符由字母、数字、下划线“_"、美元符号”$"组成,并且首字符不能是数字。
(2)不能把java关键字作为标识符。
(3)标识符没有长度限制。
(4)标识符对大小写敏感。
关键字
abstract | assert | boolean | break | byte |
---|---|---|---|---|
case | catch | char | class | continue |
default | do | double | else | enum |
extends | final | finally | float | for |
if | implements | import | instanceof | int |
interface | long | native | new | package |
privte | rotected | public | return | strictfp |
short | static | super | switch | synchronized |
this | throw | throws | transient | try |
void | volatile | while |
变量和常量
变量
- 变量是一段有名字的连续的存储空间(存储在计算机内存中)。
- 变量是程序中数据的临时存放场所,其值可以改变。
- 在使用变量时,要避免出现未赋值就是用的情况(虽然变量即使不赋值也会有默认值)。
常量
- 在java语言中,利用final关键字来定义java常量,其本质为值不可变的变量。
- Java 常量的本质是值不可变得变量,所以在声明时,就必须进行初始化。
- 常量不可再次赋值,如果强行赋值,程序会报错,并拒绝接受新值。
Java 数据类型
基本数据类型和引用数据类型
基本数据类型:
数值型(byte, short, int, long)
浮点型(float,double)
字符型(char)
布尔型(boolean)
引用数据类型:
类(class)
接口(interface)
数组
整型
Java 各整数类型有固定的表示范围和字段长度,不受具体操作系统的影响。
表示形式:十进制整数、八进制整数,以0开头,十六进制整数,以0x或0X开头。
java 语言的整型变量默认为 int 型,声明 long 型的整型变量需要在后面加上”l“或 ”L“。
浮点型
表示形式:
(1)十进制,例如:3.14,314.0
(2)科学计数法,例如:3.14e2,3.14E2,100E-2
Java 语言浮点型变量默认为 double 型,声明一个 float 变量需要在后面加上”f“或”F“。
字符型
Java 使用 Unicode 编码,一个 Unicode 编码占2个字节,一个汉字也是占2个字节,所以Java中的字符变量可以存放一个汉字。
表现形式:
(1)单引号括起来的单个字符,如:'a','汗'。
(2)单引号括起来的十六进制字符代码 ,格式为'\uXXXX',u是约定前缀(Unicode 中的第一个字母),后面的XXXX是4位十六进制数,表示该字符在Unicode中的序号。如:'\u0061'。
(3)某些特殊的字符可以用转义符 '\' 来表示,将其后面的字符转为其他含义。如:'\t' 代表制表符。
布尔型
Java 中的 boolean 类型可以表示真假,只允许取值 true 或 false(不可用 0 或非 0 的整数来替代 true 和 false。
基本数据类型的转换
整型、字符型、浮点型的数据在混合运算中互相转换时应遵循以下原则:
(1)容量小的类型自动转换成容量大的类型。
(2)byte,short,char 之间不会互相转换,三者在计算时首先会转换成int类型。
(3)容量大的数据类型转换成容量小的数据类型时,需要加上强制转换符,但可能造成精度降低或溢出。
(4)有多种类型的数据混合运算时,系统首先自动地转换成容量最大的数据类型,然后进行计算。
成员变量和局部变量
成员变量:在类的内部、方法(含语句块)外部定义的变量,作用域从变量定义位置起到类结束。
局部变量:在方法(含语句块)内部定义的变量(包括形参),作用域从变量定义位置起到方法结束。
对于Java而言,类的外面不能有变量的声明。
运算符
牢记点
Java 可以对浮点数求余。
按位左移乘 2 ,按位右移除 2 。
逻辑与、或有短路现象,按位与、或没有短路现象。
表达式的运算顺序
Java 表达式按照运算符的优先级从高到低进行运算,优先级相同的按照从左到右的方向进行运算。
流程控制
if 语句
1.基本形式
if( 表达式 ) {
代码块
}
2.if——else
if(表达式){
代码块
}else{
代码块
}
3.if——elseif ——else
if (表达式){
代码块
}else if{
代码块
}else{
代码块
}
switch 语句
switch (表达式){
case 常量1:
代码块 1
break;
case 常量2:
代码块 2
break;
default:
代码块 X;
break;
}
switch 表达式中允许的值只能是 byte、short 、int、和char类型(在JDK 7.0 中可以是 String 类型。
循环语句
while循环
while (循环条件){ 条件满足则执行代码块。
循环代码块
}
do—while循环
do {
循环代码块
}while (循环条件); 先执行1次,条件满足则继续执行。
for循环
for (表达式1; 表达式2; 表达式3){
循环代码快
}
跳转语句
break:跳出当前循环或者switch。(break 可以设置标记,跳出指定标记循环,通常用 flag 作为标记。
continue:停止当次循环,继续往下执行。
return:返回值并结束所在所有循环。
方法与数组
方法
语法形式
[修饰符] 返回值类型 方法名([形参列表]){
方法体
}
public static void add(int a, int b){
return a+b;
}
修饰符:用来规定方法的一些特征,例如它的可见范围以及如何被调用。
返回值类型:表示该方法返回什么类型的值,方法可以没有返回值,这时候需要用 void 表示返回值类型。一个方法只能有一个返回值,因此也只能有一个返回值类型。
方法名:符合标识符命名规则,并且能够望文知意。
形参列表:参数用来接收外界传来的信息,可以是一个也可以是多个,也可以没有参数,但无论是否有参数,都必须有小括号。方法中的这些参数成为形式参数,简称形参,形参必须说明参数类型。
方法的递归调用
递归调用是指一个方法在他的方法体内调用他自身。
递归调用最大的问题是,如果地柜调用没有推出的条件,则地柜方法将无休止的调用其自身。为了防止递归调用无休止的进行,必须在方法内有种植递归调用的手法,通常的做法是增加条件判断。
使用递归调用虽然使程序编写会简单一些,但是不易于理解,在实际编程过程中不建议使用递归调用。
##数组
数组是把相同类型的若干变脸按照一定顺序组织起来,这些按顺序排列的同类型数据元素的集合称为数组。
数组有两个核心要素:
相同类型的变量和按一定的顺序排序。
数组中的元素在内存中是连续存储的。
数组中的数据元素可以使基本数据类型,也可以是引用类型。
一维数组
使用数组时,需要声明、创建、赋值和使用几个步骤。
声明:
数据类型 [ ] 数组名;
或
数据类型 数组名[ ];
如:
int engNo[ ];
int [ ] engNo;
Java声明数组时不可以指定数组长度,例如:int engNo[100] 是非法的。
创建:
数组名 = new 数据类型 [ 数组长度 ];
engNo = new int[100];
声明并创建:
数据类型 [ ] 数组名 = new 数据类型 [ 数组长度 ];
int[ ] engNo = new int[100];
数据类型的默认值
基本数据类型:
整型:0;
浮点型:0.0;
字符型:'\u0000';
布尔型:false;
引用数据类型:null;
基本数据类型与引用数据类型的本质区别
内存存储形式不同是基本数据类型与引用数据类型的本质区别,引用数据类型的名称实际代表的是存放引用数据类型的地址,不是引用数据类型本身。而基本数据类型的名称代表的是数据类型本身。
值传递和引用传递
采用值传递时,其传递的实质是数值的副本,所以原数据本身不会发生改变。
采用引用传递时,其传递的实质为引用得地址,所以原数据本身发生了改变。
二维数组
Java语言允许构造多维数组存储多维数据。多维数组的数组元素有多个下标,以识别它在数组中的位置。
int [ ] [ ] arr = new int [3][4];
String 字符串
String 类
String类是最终类,不能被继承。
String字符串是常量,字符串的值在创建之后不能更改。
(再次赋值时其实是将变量重新指向新定义的string字符串对象的地址)
String类常用构造方法
构造方法 | 描述 |
---|---|
String(String s) | 初始化一个新建的String对象,使其表示一个与参数相同的字符序列。 |
String(char[ ] value) | 创建一个新建的String对象,使其表示字符数组的参数中包含当前包含的字符序列。 |
String(char[ ] value, int offset, int count) | 包含取自字符数组参数的一个子数组的字符序列。offset参数是子数组第一个字符的索引,count参数指定子数组的长度。 |
String类的使用
连接字符串
concat方法:
String s1 = "Hello";
s1.concat(" world!");
Hello world!
"+":
String S1 = "Hello";
s1 = s1 + " world!";
Hello world!
比较字符串
"==":
比较两个对象地址是否一致。
equals:
比较两个对象内容是否一致。
String 类的常用方法
P 107
StringBuffer 类
StringBuffer 代表的是可变的字符序列,可以对字符串对象的内容进行修改。
常用构造方法
构造方法 | 描述 |
---|---|
StringBuffer() | 构造一个不带字符的字符串缓冲区,初始容量为16个字符。 |
StringBuffer(String str) | 构造一个字符串缓冲区,并将其内容初始化为指定字符串内容。 |
String、StringBuffer、StringBuilder的区别
1、String 在做字符串拼接时最耗内存,拼接效率最低。
2、StringBuffer 是线程安全的,拼接效率次之。
3、StringBuilder 是线程不安全的,拼接效率最高。
类与对象
面向对象三大特性
封装
封装就是将抽象得到的属性和行为结合起来,形成一个有机的整体,也就是类。类里面的一些属性和方法(尤其是属性)需要隐藏起来,不希望直接对外公开,但同时提供供外部访问的方法来访问这些需要隐藏的属性和方法。
封装的目的是增强安全性和简化编程,使用者不必了解具体类的内部实现细节,而只是需要通过提供给外部访问的方法来有限制的访问类需要隐藏的属性和方法。
继承
Java继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的属性或新的方法,也可以用已存在的类的属性和方法。
继承的语法形式
A类继承B类
class A extends B {
类定义部分
}
this 和 super
this:代表这个类对象本身。
super:代表当前对象的直接父类对象的默认引用,在子类中可以通过super关键字来访问父类的成员。
继承和访问权限
子类可以继承父类中访问权限修饰符为 public 和 protected 的属性和方法。
子类可以继承父类中用默认访问权限修饰的属性和方法,但子类和父类必须在同一个包中。
子类无法继承父类中访问权限修饰符为 private 的属性和方法。
子类无法继承父类的构造方法。
方法重写
重写方法与被重写方法同名,参数列表也必须一致。
重写方法的返回值类型必须和被重写方法的返回值类型相同或者是其子类(返回值类型可以保持或缩小)。
重写方法不能缩小被重写方法的访问权限(访问权限可以保持相等或者扩大)。
继承中的初始化顺序
多态
向上转型
父类的引用指向子类对象。
向下转型
子类的引用指向父类对象。
构造方法
构造方法的方法名必须与类名相同。
构造方法没有返回值类型,也不能定义为 void ,在方法名前不声明返回类型。
对象初始化过程
在使用 new 关键字创建并初始化对象的过程中,具体的初始化分为 4 步:
(1)给对象的实例变量分配空间,默认初始化成员变量。
(2)成员变量声明时初始化。
(3)构造块初始化。
(4)构造方法初始化。
方法重载
在同一个类中,可以有两个或者两个以上的同名方法,但它们的参数列表不同,在这种情况下,该方法就被称为重载(overload)。
参数列表不同的三种情况:
(1)参数的数量不同。
(2)参数的类型不同。
(3)参数的顺序不同。
包和访问控制
Java包
包是类的容器,用于分隔类名空间。如果没有指定包名,所有的类都属于一个默认的无名包。
包的作用
(1)提供了类似于操作系统树形文件夹的组织形式,能分门别类的存储、管理类,易于查找并使用类。
(2)解决了同名类的命名冲突问题。
(3)包允许在更广的范围内保护类、属性和方法。
包的使用
package java.util.*;
程序中如果有package语句,该语句一定是文件中的第一条可执行语句,它的前面只能有注释或者空行。
一个文件中最多只能有一条 package 语句。
访问权限
修饰符 | 类内部 | 同一包内 | 子类 | 任何地方 |
---|---|---|---|---|
private | yes | |||
default | yes | yes | ||
protected | yes | yes | yes | |
public | yes | yes | yes | yes |
static
静态变量
声明为 static 的变量称为静态变量或者类变量。
可以直接通过类名引用静态变量,也可以通过实例名来引用静态变量。
类的所有实例共同拥有一个静态变量。
静态方法
声明为 static 的方法称为静态方法或类方法。
静态方法可以直接调用静态方法,访问静态变量,但是不能直接访问实例变量和实例方法。
静态方法中不能使用 this 关键字,因为静态方法不属于任何一个实例。
静态方法调用实例变量报错
public class Student{
public int avgAge = 22; //实例变量
public static void showAvgAge(){
System.out.println("静态方法调用实例变量");
}
}
//报错:无法从静态上下文中引用非静态变量 avgAge
Java 静态块
static {
语句块
}
静态块和静态变量是在类首次装载进 JVM 时执行的。
抽象类和接口
抽象类和抽象方法
抽象类
abstract class 类名 {
}
抽象方法
其他修饰符 abstract 返回值 方法名();
抽象类的使用
父类
abstract class Person {
String name = "人";
String color = "肤色";
// 定义吃饭的抽象方法
public abstract void eat();
// 定义工作的抽象方法
public abstract void work();
}
子类
class Chinese extends Person {
String houseHold = "北京";
// 实现父类 eat() 的抽象方法
public void eat(){
System.out.println("中国人用筷子吃饭!");
}
// 实现父类 work() 的抽象方法
public void work(){
System.out.println("中国人勤劳工作!");
}
}
抽象类的特征
(1)抽象类不能被直接实例化。
(2)抽象类的子类必须实现抽象方法,除非子类也是抽象类。
(3)抽象类里可以有普通方法,也可以有抽象方法,但是有抽象方法的类必须是抽象类。
接口
接口的概念
接口是一系列 方法的声明,是一些抽象方法的集合。
一个接口只有方法的声明,没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现类可以具有不同的行为。
接口的语法形式
[修饰符] interface 接口名 [extends] [接口列表]{
接口体
}
interface 前的修饰符是可选的,没有时代表默认权限,如果使用修饰符,则只能用 public ,表示此接口是公有的。
extends 用来直接定义父接口,一个接口可以继承多个父接口,当 extends 后面有多个父接口时,用逗号隔开。
类实现接口的语法形式
[修饰符] class 类名 implements 接口列表 {
类体
}
类实现接口用 implements 关键字,Java中的类只能是单继承的,但一个 Java 类可以实现多个接口,这也是Java 解决多继承的方法。
接口的特征
(1)接口中不允许有实体方法。
例如:
public void show(){}
报错:接口方法不能带主体,即大括号。
(2)接口中可以有成员变量,默认修饰符是 public static final ,接口中的抽象方法必须用 public 修饰。
(3)一个类可以实现多个接口。
(4)接口可以继承其他接口,实现接口合并的功能。
评论区