Java 基础概述(上)
- Java 基础概述
- Java 基础语法
- 关键字
- 标识符
-
- 变量与常量
-
- 数据类型
-
- 运算符
- 流程控制
-
- 数组
-
- 面向对象
- 类与对象
-
- 面向对象
-
- instanceof 与类型转换
-
- Object 类
-
- static 关键字
-
- final 关键字
- 抽象类与抽象方法
- 接口
-
- 内部类
Java 基础概述
- Java 具有面向对象、跨平台、健壮性等特点,按照应用范围分为三个版本:JavaSE、JavaEE、JavaME;
- JavaSE 的结构组成:
- JDK:Java 开饭环境的核心组件,提供编译、调试以及运行 Java 程序的所有工具;
- JRE:Java 运行时环境,是 JVM 的实现,提供了运行 Java 程序的平台。JRE 包含 JVM,但不包含 Java 编译器、调试器等开发工具;
- JVM:程序运行时,JVM 负责执行指令,管理数据、内存、寄存器,JVM 屏蔽了底层运行平台的差异,实现了“一次编译,到处运行”;
Java 基础语法
关键字
- 定义:被 Java 语言赋予了特殊含义,存在专门用途的字符串。
- 特点:关键字中所有的字母均为小写。
- 示例以及分类:
- 数据类型关键字:byteshortintlongfloatdoublebooleanchar
- 流程控制关键字:ifelseswitchcasedefaultwhiledobreakcontinuereturn
- 类、方法、实例、变量关键字:privateprotectedpublicvoidabstractfinalstaticsynchronizedextendsimplementsnewthissuperinstanceof
- 异常处理关键字:trycatchfinallythrowthrows
- 用于包的关键字:packageimport
- 其他修饰符关键字:nativestrictfptransientvolatileassert
- 数字类型值的字面值:truefallnull
- 保留字:gotoconst
标识符
Java 对于各种变量、方法、类等要素命名时使用的字符序列均称为标识符,即需要自己命名的地方都称为标识符。
标识符的合法规则
- 由 a-z、A-Z、0-9、_、$ 组成;
- 严格区分大小写,长度无限制;
- 不可以以数字开头;
- 不可以使用关键字和保留字,但是可以包含关键字和保留字;
- 不能包含空格;
名称命名规范
- 包名:多单词组成时所有字母小写:xxxyyyzzz
- 类名、接口名:多单子组成时所有单侧的首字母大写:XxxYyyZzz
- 变量名、方法名:多单词组成时,第一个单词的首字母小写,后续单词的首字母大写:xxxYyyZzz
- 常量名:所有字母大写。多单词组成时每个单词之间使用下划线分割:AAAAXXX_YYY_ZZZ
变量与常量
变量
- 变量的概念
- 变量时内存中的一个存储单元,该区域的数据可以在同一类型范围内不断的变化;
- 变量时程序中最基本的存储单元,其包含变量类型、变量名以及存储的值;
- 变量的分类
- 成员变量
- 类变量:方法之外的变量,以static修饰;
- 实例变量:方法之内的变量,不以static修饰;
- 局部变量:类的方法或者代码块中的变量;
常量
- 一种特殊的变量,其值在被设定后,在程序的运行过程当中不允许改变;
- 常量的声明:final <数据类型> <变量名> = <初始化值>;,例如final double PI = 3.14;
数据类型
Java 是一种强类型语言,每个变量都必须声明类型。
数据类型的分类
- 数据类型
- 基本数据类型
- 数值类型
- 整数类型(byteshortintlong)
- 浮点类型(floatdouble)
- 字符类型(char)
- 布尔类型(boolean)
- 引用数据类型
- 类(class)(String类型是一个类,属于引用数据类型)
- 接口(interface)
- 数组([])
基本数据类型
| 类型 | 存储空间 | 取值范围 | 默认值 | 包装类 |
|---|
| byte | 1字节 | -128~127 | (byte)0 | Byte |
| short | 2字节 | -32786~32767 | (short)0 | Short |
| int | 4字节 | -2的31次方~+2的31次方减1 | 0 | Integer |
| long | 8字节 | -2的63次方~+2的63次方减1 | 0L | Long |
| float | 4字节 | 3.4e-45~1.4e38 | 0.0F | Float |
| double | 8字节 | 4.9e-324~1.8e308 | 0.0 | Double |
| char | 2字节 | unicode 字符,使用单引号括起来 | ‘u0000’ | Character |
| boolean | 1字节 | truefalse | false | Boolean |
基本数据类型的转换
- 自动类型转换
- 容量小的数据类型可以自动转换为容量大的数据类型;
- byteshortchar --> int --> long -->float --> double,intlong转换为floatdouble可能会出现数据丢失的问题;
- 运算
- 多种数据类型参与运算时,系统首先自动将所有数据类型转换为容量最大的那种数据类型,然后再进行运算;
- byteshortchar三者是平级的,因此不能相互转换,他们三者在进行运算时首先转换为int类型;
- boolean类型不能与其他数据类型进行运算;
- 当任何基本数据类型与字符串String进行连接运算+时,基本数据类型将自动转化为String类型;
运算符
| 运算符 | 种类 |
|---|
| 算术运算符 | +, -, *, /, %, ++, -- |
| 赋值运算符 | =, +=, -=, *=, /= |
| 关系运算符 | >, <, >=, <=, ==, !=, instanceof |
| 逻辑运算符 | &, |, !, ^, &&, ||, ! |
| 三元运算符 | 条件 ? 执行语句1 : 执行语句2 |
| 位运算符 | &, |, ^, ~, >>, >>, >>> |
- instanceof:是否为某类的对象,"hello" instanceof String; // true
- 逻辑运算符用于连接布尔类型表达式
- &和&&的区别:前者左右表达式均需要运算;后者中若左边表达式为假,则右侧表达式不参与运算
- |和||的区别:前者左右表达式均需要计算;后这种若左边表达式为真,则右侧表达式不参与计算
- ^异或:左右表达式相同时为 false,不同时为true
- 位运算符:应用于byteshortintlongchar等类型,位运算符作用在所有位上,并且按位进行运算
流程控制
- 顺序结构
- 分支结构
- 根据条件选择性的执行某段代码
- if..else和switch..case..两种分支语句
- switch..case语句的注意事项:
- switch 表达式的值只能为以下几种数据类型:byteshortintcharEnumString;
- case 子句中的值必须为常量,不能是变量或者不确定的值;
- break用于在执行完一个 case 分支后跳出,若没有 break 程序会顺序执行到 switch 代码块尾部;
- default子句是可以任选的,当没有匹配到 case 时,执行 default。default 位置任意,但建议放在最后;
- 循环结构
- 根据循环条件,重复性的执行某段代码
- while、do...while、for三种循环语句
- for循环的初始化部分可以声明多个变量,但必须是同一个类型,使用逗号分隔,循环条件处可以有多个变量更新,逗号分隔;
- while循环中不要忘记条件的迭代部分,否则陷入死循环;
- do..while循环至少执行一次循环体;
- JDK 1.5 提供了foreach循环,便于遍历集合、数组元素
break 与 continue
- break用于终止某个代码块的执行,只能用于switch和循环语句当中;
- continue用于跳过一次循环体的执行,进入下一次循环,故只能用在循环体当中;
- 可以通过带标签的break labelcontinue label来指定对哪一层循环进行操作;
数组
数组概述
- 定义:数组时多个相同类型的数据按照一定顺序排列的集合;
- 特点:
- 数组本身为引用数据类型,但其中的元素可以是任何数据类型;
- 数组的长度一旦确定,不能再修改;
- 数组中的数据称为元素,每个元素都可以通过下标直接访问;
- 创建数组对象会在内存当中开辟一段连续的空间,数组名中引用的就是这块连续空间的首地址,数组对象本身是在堆中存储的;
Java 内存的几个概念
- 堆(heap)
- 存放 new 的对象实例或者数组,所有线程共享;
- 实例变量(即成员变量)与对象关联在一起,故也在堆中存储;
- 对象不再被使用时,会在不确定的时间被垃圾回收器回收;
- 栈(stack)
- 存放局部变量(基本数据类型–值、引用数据类型–对象在堆中的地址),是线程的私有区域;
- 数据用完时所占空间自动释放;
- 方法区(Method Area)
- 存储被 java 虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等,所有线程共享;
数组的声明与初始化
- 声明方式
- int[] a或者int a[]
- 多维数组:int a[][]或int[][] a
- 初始化
- 静态初始化:定义数组的同时为数组元素分配空间并赋值;
- 动态初始化:数组声明和为元素分配空间的操作与赋值操作分开进行;
- 默认初始化:数组一旦被分配空间,其内部的元素也将根据类型被初始化;
数组的使用
- 遍历:可以使用基本循环(forwhiledo..while..)或增强for循环遍历;
- 数组工具类Arrays
- Arrays.toString:数组转字符串
- Arrays.sort:数组排序
- Arrays.binarySearch:二分查找(使用二分查找需要先将数组排序)
- Arrays.fill:元素填充
- Arrays.asList:转换为 List 集合
- Arrays.equals:数组比较
- Arrays.copyOf:数组复制
面向对象
类与对象
- 类是对一类事物的描述,是抽象的、概念上的定义;
- 类的访问机制:
- 在一个类中的访问机制:类中的方法可以直接访问类中的成员变量(例外:static的方法不能访问非static的成员变量);
- 不同类中的访问机制:先创建要访问的类的对象,在通过对象访问类中定义的成员;
- 对象是实际存在的某一类事物的单独个体,因此也成为实例(instance);
- 创建:类名 对象名 = new 类名;
- 使用对象名.对象成员的方式可以访问对象成员,包括属性和方法;
- 对象内存分析:一个实例化后的对象,会在堆中被分配内存,并将这个堆地址存放在栈中相应的变量处;
类的成员变量与局部变量
| 成员变量 | 局部变量 |
|---|
| 声明位置 | 直接声明在类中 | 在方法形参或内部、代码块、构造器内声明 |
| 修饰符 | private/public/static/final | 不能用权限修饰符修饰,可以用final修饰 |
| 初始化值 | 有默认的初始化值 | 无默认初始化值,除形参外必须显式的进行初始化 |
| 内存位置 | 堆内存(非static)或方法区(static) | 栈内存 |
类的方法
- 方法的重载
- 在一个类中,允许存在一个以上的同名方法,只要他们的参数个数或者参数类型不同即可,与返回值无关;
- 示例:
- int add(int x, int y)
- int add(int x, int y, int z)
- double add(double x, double y)
- 可变个数的形参
- 声明格式:方法名(参数的类型... 参数名);
- 可变形参一般放在最后声明;
- 一个方法最多只能声明一个可变形参;
- 可变形参与使用数组一致;
- 方法参数的传递
- Java 中方法参数的传递只有一种方式:值传递,即实际传入的是参数值的副本,参数本身不受影响;
- 对于基本数据类型:变量的“数据值”传递给形参;
- 对于引用数据类型:变量的“地址值”传递给形参;
类的构造器
- 特征
- 与类的名字相同;
- 不声明返回值的类型;
- 不能被staticfinalsynchronizedabstractnative修饰;
- 作用
- 使用new创建对象时必须使用类的构造器;
- 用于给类中的属性初始化赋值;
- 分类
- 隐式无参构造器(系统默认提供);
- 也可以显式的定义一个或者多个构造器(有参、无参);
- 注意
- 每个类都至少有一个构造器;
- 默认构造器的修饰符与所属类的修饰符一致;
- 一旦显式的定义了构造器,系统则不在提供默认的构造器;
- 父类的构造器不能被子类继承;
- 一个类可以创建多个重载的构造器;
面向对象
面向对象:封装
- 隐藏对象内部的复杂性,只对外公开简单的接口
- 目的:为了限制不合理的操作
权限修饰符
| 修饰符 | 类内部 | 同一个包 | 不同包的子类 | 同一个工程 |
|---|
| private | √ | | | |
| 缺省 | √ | √ | | |
| protected | √ | √ | √ | |
| public | √ | √ | √ | √ |
- class 的权限只有public和default(缺省)
- 上述四种都可以用来定义类成员的访问权限
面向对象:继承
- 特征:若多个类中存在相同的属性和行为,那么可以将这些内容单独抽取到一个类当中,其他的类继承这个类即可
- 作用
- 降低代码冗余度,提高代码复用性
- 有利于功能的扩展
- 类与类之间产生了关系,提供了多态的前提
- 规则
- 子类继承父类,就继承了父类非private的属性和方法,子类是父类的扩展
- 类与类之间是单继承的,接口是多继承的
继承–重写
- 定义:在子类中可以对从父类继承的方法进行改造,程序执行时子类的方法将覆盖父类的方法
- 注意
- 重写的方法必须与父类被重写方法拥有相同的方法名称、参数列表
- 重写的方法的返回值类型不能大于父类被重写方法的返回值类型
- 重写的方法的访问权限不能小于父类被重写方法的访问权限
- 父类的静态方法不能被子类重写为非静态方法;父类的非静态方法也不能被子类重写为静态方法(两种情况都将编译出错)
- 私有方法不能被子类重写
继承–super关键字
使用super关键字可以访问或者调用父类中的属性、方法、构造器,其追溯不仅限于直接父类。
super与this的区别:
| 区别点 | super | this |
|---|
| 访问属性 | 直接访问父类中的属性 | 访问本类中的属性,若本类中无此属性则从父类中继续查找 |
| 调用方法 | 直接访问父类中的方法 | 访问本类中的方法,若本类中无此方法则从父类中继续查找 |
| 调用构造器 | 调用父类构造器,必须放在子类构造器的首行 | 调用本类构造器,必须放在构造器的首行 |
面向对象:多态
- 对象的多态性:父类引用指向子类对象
- Java 引用变量有两个类型:编译时类型和运行时类型。编译时类型由声明该变量是使用的类型决定,运行时类型由实际赋给该变量的对象决定
- 多态的作用:提高代码的通用性
- 多态的前提:要存在继承或者实现关系,需要子类重写父类的方法
对象的多态性
- 一个变量只能有一种确定的数据类型
- 一个引用类型的变量可以指向多种不同类型的对象
- 一个引用类型变量如果声明为父类的类型,但实际引用的确实子类的对象,那么该变量便不能访问子类中新添加的属性和方法
- 多态是方法的多态,属性没有多态性
instanceof 与类型转换
- x instanceof Y:检验对象 x 是否为类 Y 的对象,返回值为boolean
- 要求 x 所属的类与 Y 类必须是子类和父类的关系,否则编译错误
- 结果取决于变量 x 所指向的对象的实际类型是不是 Y 类型的子类
对象的类型转换
- 从子类向父类的类型转换自动进行
- 从父类到子类的类型转换需要强制类型转换实现
- 无继承关系的引用类型的类型转换是非法的
Object 类
- Object是所有 Java 类的根父类,未声明extend关键字的类的父类默认为java.lang.Object
- 常用方法
- public boolean equals(Object obj):对象比较
- public String toString():转字符串,返回类名和它的引用地址,可以根据需要重写
== 与 equals
- ==
- 基本数据类型比较的是数值,两个变量值相等即为 true
- 引用数据类型比较的是地址,两个变量指向同一个对象即为 true
- equals
- 只能比较引用类型,未被重写的equals与==作用相同,比较的是地址值
- 对于File、String、Date以及包装类来说,比较的是类型以及内容(因为这些类重写了equals())
static 关键字
- 类属性和类方法
- 类属性是各个对象之间共享的变量,不因对象的不同而改变;
- 类方法与对象无关,不需要创建对象就可以调用类方法;
- static使用范围:属性、方法、代码块、内部类
static 修饰的特点
- 随着类的加载而加载,属于类本身,优先于对象存在
- 被修饰的成员被所有对象共享
- 访问权限允许时,可以不创建对象,直接通过类调用
- 静态变量在内存中只有一份,被所有实例共享
- this和super无法在静态方法中使用;静态方法不能被重写;静态方法与非静态方法不能互相访问(加载顺序不同)
代码块
- 作用:一般用于堆 Java 对象或者类进行初始化
- 静态代码块
- 可以对类的属性、类的声明进行初始化操作,可以有输出语句
- 不可以调用非静态的方法
- 若有多个静态代码块,则按照从上往下顺序执行,执行优先于非静态代码块
- 静态代码块随着类的加载而加载,且只执行一次
- 非静态代码块
- 可以对类的属性、类的声明进行初始化操作,可以有输出语句
- 可以调用非静态的结构,还可以调用静态的变量或者方法
- 若有多个非静态代码块,则按照从上往下顺序执行
- 每次创建对象的时候,都会执行一次,且先于构造器执行
final 关键字
- final修饰类:表示该类不可被继承
- final修饰方法:表示该方法不能被子类重写
- final修饰变量:表示为常量,该量只能被赋值一次,且必须在声明/在每个构造器中/代码块中显示的赋值才能使用
抽象类与抽象方法
- 抽象类:将一个父类设计得非常抽象以至于没有具体的实例,称为抽象类,使用abstract关键字修饰
- 抽象方法:只有方法的声明,没有方法的实现,且以分号结束,称为抽象方法,使用abstract关键字修饰
- 关系:抽象类中可以没有抽象方法;有抽象方法的类一定要声明为抽象类
- 特点:
- 抽象类不能被实例化,抽象类是用来被继承的
- 抽象类的子类必须实现抽象方法,若没有重写全部的抽象方法,该子类仍然为抽象类
- 不能使用abstract修饰变量、代码块、构造器
- 不能使用abstract修饰私有方法、静态方法、final的方法、final的类
接口
- 定义:接口是抽象方法和常量值定义的集合,接口是一种规范,定义的是一组行为准则,使用interface修饰
- 特点:
- 接口中没有构造器
- 接口中的所有成员变量默认使用public static final修饰
- 接口中的所有抽象方法默认使用static abstract修饰
- 接口采用多继承机制,实现接口的类必须实现接口中的所有方法
- 接口用于被实现类实现,其与实现类之间存在多态性
- 改进:Java 8 为接口添加了静态方法和默认方法
接口和抽象类的对比
| 区别点 | 抽象类 | 接口 |
|---|
| 定义 | 包含抽象方法的类 | 抽象方法和全局常量的集合 |
| 组成 | 构造方法、抽象方法、普通方法、常量、变量 | 常量、抽象方法;(1.8 新增)默认方法、静态方法 |
| 使用 | 子类继承抽象类extend | 子类实现接口interface |
| 关系 | 抽象类可以实现多个接口 | 接口不能继承抽象类,但允许继承多接口 |
| 常见设计模式 | 模板方法 | 工厂模式、代理模式 |
| 对象 | 通过对象的多态性产生实例化对象 | 通过对象的多态性产生实例化对象 |
| 局限 | 单继承 | |
| 本质 | 模板 | 行为规范 |
| 选择 | | 优先使用接口以避免单继承 |
内部类
- 内部类
- Java 中允许在一个类的内部定义另一个类,前者称外部类,后者为内部类
- 内部类一般定义在他的类或者语句块之内,在外部引用是必须给出完整的名称
- 分类
- 成员内部类:可以调用外部类的结构
- 静态内部类:static修饰
- 局部内部类:在一个方法内部声明一个类,可以调用外部类的结构
- 匿名内部类:不需要定义,需要使用的时候临时实现内部类,随之使用