Java基础总结1
一、Java语言概述
1、开发环境的搭建
1.1、官网下载并安装JDK
JDK、JRE、JVM的关系
1、JRE(Java Runtime Environment Java运行环境): 包括Java虚拟机和Java程序所需的核心类库
2、JDK(Java Development Kit Java开发工具包): JDK提供给Java开发人员使用,包含Java的开发工具和JRE
(其中的开发工具:编译工具javac.exe 打包工具jar.exe, 简言之:使用JDK开发完成的java程序,交给jre去运行 )
1.2 、配置环境变量
为什么配置path环境变量?
- path环境变量: windows操作系统执行命令时所要搜寻的路径
- 为什么要配置path:希望java的开发工具(javac.exe,java.exe)在任何的文件路径下都可以执行成功。
PATH: 目的是可以在任意目录下找到java和javac命令
CLASSPATH: 让指定的class文件可以在任意目录下找到
2、程序的编写
二、基本语法
1、关键字与标识符
关键字: 被Java语言赋予特定含义的单词 一共50+2(保留字goto和const)
标识符: 给类,接口,方法,变量起名字时使用的字符序列(凡是自己可以起名字的地方都叫标识符)
标识符命名规则: ① 由字母,数字,_或$组成 ② 不能以数字开头
2、变量
2.1 、按数据类型分类:基本数据类型和引用数据类型
- 基本数据类型容量从小到大(数的范围大和小): byte (1字节 )、 char (2字节)、short (2字节) ->int (4字节) ->long ( 8字节) ->float (4字节) -> double (8字节) boolean (只能取true或false)
自动类型转换: 在参与运算时,会自动提升到int类型和double类型(只涉及7种基本数据类型)
强制类型转换: 高精度转低精度 (大盒子装小盒子)
- 引用数据类型: 类class,接口interface,数组[ ]
2.2、 按声明的位置分类
3、运算符
1、算术运算符: ±*/%(前)++ (后) ++(前) (后)-- 连接符+ (只能使用在String与其他数据类型变量之间)
2、赋值运算符: = += -= = /= %=
3、*比较运算符(关系运算符): == != > < >= <= instanceof
4、逻辑运算符:** & | ||(短路或,左真右不运算)&&(短路与,左假右不运算) ! ^
5、位运算符: << >> >>> & | ^ ~
6、三元运算符:** (条件表达式)? 表达式1 : 表达式2
4、流程控制
1、顺序结构: 程序从上到下执行。
2、分支结构: if-else if - else switch-case
说明: ① 针对于条件表达式:如果多个条件表达式之间有包含的关系,通常情况下,需要将范围小的声明在范围大的上面。否则,范围小的就没机会执行了。② switch结构中的表达式, 只能是如下的6种数据类型之一: byte 、short、char、int、枚举类型(JDK5.0新增)、String类型(JDK7.0新增)
3、循环结构: for while do-while
循环结构的四要素: ① 初始化条件 ② 循环条件 —>是boolean类型 ③ 循环体 ④ 迭代条件
键盘录入
a:导包 import java.util.Scanner;
b:创建键盘录入对象 Scanner sc = new Scanner(System.in);
c:调用方法接收键盘录入的数据
sc.nextInt() 接收一个int类型的数据
sc.next() 接收一个字符串
说明: Scanner是一个扫描器,我们录取到键盘的数据,先存到缓存区等待读取,它判断读取结束的标示是 空白符;比如:空格,回车,tab 等等。其中nextLine()方法的结束符只是Enter键,即nextLine()方法返回的是Enter键之前的所有字符,它是可以得到带空格的字符串的,所以一定要注意next()方法和nextLine()方法的连用。
三、数组
1、数组的概述
1、 数组的理解: 数组(Array),是多个相同类型数据一定顺序排列的集合,并使用一个名字命名, 并通过编号的方式对这些数据进行统一管理。
2、 数组相关的概念: 数组名,元素角标,下标、索引,数组的长度:元素的个数。
3、 数组的特点: ① 数组是序排列的 ② 数组属于引用数据类型的变量。数组的元素,既可以是基本数据类型,也可以是引用数据类型 ③ 创建数组对象会在内存中开辟一整块连续的空间 ④ 数组的长度一旦确定,就不能修改。
4、 数组的分类: ① 按照维数:一维数组、二维数组、。。。 ② 按照数组元素的类型:基本数据类型元素的数组、引用数据类型元素的数组。
2、一维数组和二维数组
2.1、一维数组的声明与初始化:
//静态初始化int[] num ;//声明
num =newint[]{1,3,5,7,9};//数组的初始化和数组元素的赋值操作//动态初始化int[] num =newint[5];
一维数组元素的默认初始化值
数组元素是整型: 0
数组元素是浮点型: 0.0
数组元素是char型: 0 或’\u0000’,而非’0’
数组元素是boolean型: false
数组元素是引用数据类型: null
一维数组内存解析:
2.2、二维数组的声明与初始化:
//静态初始化int[][] num =newint[][]={{1,3,5},{2,3},{2,3,4,5}};//动态初始化int[][] num =newint[3][2];
二维数组内存解析:
3、数组的常见算法
3.1、冒泡排序
原理:
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
publicclassBubbleSort{publicstaticvoidmain(String[] args){int[] nums ={121,54,38,21,56,32};//外层循环控制的是,比较的轮数//外层循环次数 length-1int temp;for(int i =0; i < nums.length-1; i++){//内层循环控制的是每轮比较的次数//第i轮(i从0开始计算),比较次数为:length-i-1for(int j =0; j < nums.length - i -1; j++){if(nums[j]>nums[j+1]){//两两相比,满足移动条件
temp = nums[j];
nums[j]=nums[j+1];
nums[j+1]=temp;}}}//排序已完成,下面是遍历打印查看的过程for(int i =0; i < nums.length; i++){System.out.print(nums[i]+" ");}}}
3.2、选择排序
原理:
- 将整个数组遍历一遍,将最小的数和首个元素互换
- 然后将第二个到最后的数组遍历,其中最小的和第二个互换,以此类推。
publicclassSelectSort{publicstaticvoidselectSort(int[] nums){int length = nums.length;if(length ==0){return;}int min =0;int minIndex =0;for(int i =0; i < length; i++){
min = nums[i];
minIndex = i;for(int j = i +1; j < length; j++){if(nums[j]< min){
min = nums[j];
minIndex = j;}}if(minIndex != i){swap(nums, i, minIndex);}}}publicstaticvoidswap(int[] nums,int i,int j){int temp = nums[i];
nums[i]= nums[j];
nums[j]= temp;}}
3.3、二分查找(折半查找)
二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,二分查找要求数组数据必须采用顺序存储结构有序排列。
原理:
- 假设数组中的值按照某个顺序排序后,我们在数组中查找某个元素的位置。
- 我们将要查找的值和数组中间的值进行比较
- 如果中间的值比我们要查找的值大,那么说明我们要查找的值在中间值的左边,反之,就在右边。
publicclassBinarySearch{/**
* 二分查找(折半查找)
*/publicstaticvoidmain(String[] args){int[] nums ={10,20,30,40,50,60,70,80,90};//要查找的数据int num =80;//关键的三个变量://1. 最小范围下标int minIndex =0;//2. 最大范围下标int maxIndex = nums.length-1;//3. 中间数据下标int centerIndex =(minIndex+maxIndex)/2;while(true){System.out.println("循环了一次");if(nums[centerIndex]>num){//中间数据较大
maxIndex = centerIndex-1;}elseif(nums[centerIndex]<num){//中间数据较小
minIndex = centerIndex+1;}else{//找到了数据 数据位置:centerIndexbreak;}if(minIndex > maxIndex){
centerIndex =-1;break;}//当边界发生变化, 需要更新中间下标
centerIndex =(minIndex+maxIndex)/2;}System.out.println("位置:"+centerIndex);}}
4、Arrays工具类的使用
- ① 定义在java.util包下 ② Arrays:提供了很多操作数组的方法。
- 使用:
//1.boolean equals(int[] a,int[] b):判断两个数组是否相等。int[] arr1 =newint[]{1,2,3,4};int[] arr2 =newint[]{1,3,2,4};boolean isEquals =Arrays.equals(arr1, arr2);System.out.println(isEquals);//2.String toString(int[] a):输出数组信息。System.out.println(Arrays.toString(arr1));//3.void fill(int[] a,int val):将指定值填充到数组之中。Arrays.fill(arr1,10);System.out.println(Arrays.toString(arr1));//4.void sort(int[] a):对数组进行排序。Arrays.sort(arr2);System.out.println(Arrays.toString(arr2));//5.int binarySearch(int[] a,int key)int[] arr3 =newint[]{-98,-34,2,34,54,66,79,105,210,333};int index =Arrays.binarySearch(arr3,210);if(index>=0){System.out.println(index);}else{System.out.println("未找到");}
四、面向对象(上)
1、类与对象
面向对象学习的三条主线:
1、Java类及类的成员: 属性、方法、构造器;代码块、内部类
2、面向对象的大特征: 封装性、继承性、多态性、(抽象性)
3、其它关键字: this、super、static、final、abstract、interface、package、import等
1.1、对象的创建与对象的内存解析:
1.2、匿名对象:
我们创建的对象,没显式的赋给一个变量名。即为匿名对象
特点: 匿名对象只能调用一次。
- 应用场景:
PhoneMall mall =newPhoneMall();//匿名对象的使用
mall.show(newPhone());
其中,
classPhoneMall{publicvoidshow(Phone phone){
phone.sendEmail();
phone.playGame();}}
1.3、JVM内存结构:
- 编译完源程序以后,生成一个或多个字节码文件。
- 我们使用JVM中的类的加载器和解释器对生成的字节码文件进行解释运行。意味着,需要将字节码文件对应的类加载到内存中,涉及到内存解析。
- 虚拟机栈,即为平时提到的栈结构。我们将局部变量存储在栈结构中,将new出来的结构(比如:数组、对象)加载在对空间中。
- 补充:对象的属性(非static的)加载在堆空间中。
- 方法区:类的加载信息、常量池、静态域
2、封装性
程序设计追求 “高内聚,低耦合”
内聚: 每个模块尽可能独立完成自己的功能,不依赖于模块外部的代码。
耦合: 模块与模块之间接口的复杂程度,模块之间联系越复杂耦合度越高,牵一发而动全身。
封装性思想的体现:
1、将类的属性私有化,同时对外提供get,set方法来获取属性的值
2、单例模式(将构造器私有化)
3、如果不希望类在包外被调用,可以将类设置为缺省
Java权限修饰符:
说明: 4种权限都可修饰类的内部结构:属性、方法、构造器、内部类,而修饰类只能使用:缺省,public
3、成员变量(属性)和局部变量区别
① 声明位置不同: 成员变量直接定义在类的{ }中;局部变量声明在方法内,方法形参,代码块内,构造器形参,构造器内。
② 权限修饰符不同: 成员变量有private,缺省,protected,public;而局部变量不可以使用权限修饰符。
③ 默认初始值不同: 类的属性,根据其类型,都默认初始化值。
整型(byte、short、int、long:0)
浮点型(float、double:0.0)
字符型(char:0 (或’\u0000’))
布尔型(boolean:false)
而局部变量没有默认初始值,所以在调用局部变量之前,要显式赋值。
4、构造器
作用: 创建对象,初始化对象信息
说明: ① 如果没有显式的定义类的构造器,则系统默认提供一个空参的构造器 ② 一个类中定义的多个构造器,彼此构成重载
属性的赋值先后顺序:
① 默认初始化
② 显式初始化
③ 构造器中初始化
④ 通过"对象.方法"或"对象.属性"的方式赋值
JavaBean的概念: 是指符合如下标准的Java类
- 类是公共的
- 是一个无参的公共的构造器
- 属性,且对应的get,set方法
5、关键字:this
理解为当前对象或当前正在创建的对象
说明: ① 如果方法或构造器的形参和类的属性同名时,我们必须显式的使用"this.变量"的方式,表明此变量是属性,而非形参 ② 构造器不能通过’'this(形参列表)“方式调用自己 ③ 如果一个类中有n个构造器,,则最多有n-1个构造器使用了"this(形参列表)” ④ 规定:"this(形参列表)“必须声明在当前构造器的首行 ⑤ 构造器内部,最多只能声明一个"this(形参列表)”,用来调用其他的构造器
6、关键字:package,import
package:
1、为了更好的实现项目中类的管理,提供包的概念
2、使用package声明类或接口所属的包,声明在源文件的首行
3、包,属于标识符,遵循标识符的命名规则、规范
4、每"."一次,就代表一层文件目录
例如:MVC设计模式
import:
- JDK中主要包的介绍
1、java.lang ——包含一些Java语言的核心类,如String、Math、Integer、System和Thread,提供常用功能。
2、java.net ——包含执行与网络相关的操作的类和接口。
3、java.io ——包含能提供多种输入/输出功能的类。
4、java.util ——包含一些实用工具类,如定义系统特性、接口的集合框架类、使用与日期日历相关的函数。
5、java.text ——包含了一些java格式化相关的类
6、java.sql ——包含了java进行JDBC数据库编程的相关类/接口
7、java.awt ——包含了构成抽象窗口工具集(abstract window toolkits)的多个类,这些类被用来构建和管理应用程序的图形用户界面(GUI)。
- 导入说明
1、 在源文件中显式的使用import结构导入指定包下的类、接口
2、 声明在包的声明和类的声明之间
3、如果需要导入多个结构,则并列写出即可
4、可以使用"xxx."的方式,表示可以导入xxx包下的所结构
5、如果使用的类或接口是java.lang包下定义的,则可以省略import结构
6、如果使用的类或接口是本包下定义的,则可以省略import结构
7、如果在源文件中,使用了不同包下的同名的类,则必须至少一个类需要以全类名的方式显示。
8、使用"xxx."方式表明可以调用xxx包下的所结构。但是如果使用的是xxx子包下的结构,则仍需要显式导入
9、import static:导入指定类或接口中的静态结构:属性或方法。
五、面向对象(中)
1、继承性
1.1、为什么要有类的继承性?
- 减少了代码的冗余,提高了代码的复用性
- 便于功能的扩展
- 为之后多态性的使用,提供了前提
1.2、继承的格式
class A extends B{ }
- 说明: A:子类、派生类、subclass B:父类、超类、基类、superclass
1.3、Java中继承性的说明
- 1、一个类可以被多个子类继承。
- 2、Java中类的单继承性:一个类只能有一个父类
- 3、子父类是相对的概念。
- 4、子类直接继承的父类,称为:直接父类。间接继承的父类称为:间接父类
- 5、子类继承父类以后,就获取了直接父类以及所间接父类中声明的属性和方法
2、方法的重写
2.1、什么是方法的重写(override 或 overwrite)?
子类继承父类以后,可以对父类中同名同参数的方法,进行覆盖操作.
2.2、重写的规则
方法的声明: 权限修饰符 返回值类型 方法名(形参列表) throws 异常的类型{//方法体}
1、子类重写的方法的方法名和形参列表与父类被重写的方法的方法名和形参列表相同
2、子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符
特殊情况:子类不能重写父类中声明为private权限的方法
3、返回值类型:
父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是void
父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值类型可以是A类或A类的子类
父类被重写的方法的返回值类型是基本数据类型(比如:double),则子类重写的方法的返回值类型必须是相同的基本数据类型(必须也是double)
4、子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型
子类和父类中的同名同参数的方法要么都声明为非static的(考虑重写,要么都声明为static的(不是重写)。
2.3、重写(Override)和重载(Overload)的区分
(1) 概念上: ① 重载: 在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同甚至是参数顺序不同)则视为重载。同时,重载对返回类型没有要求,可以相同也可以不同。 ② 重写: 就是在子类中把父类本身有的方法重新写一遍,在方法名,参数列表,返回类型都相同的情况下, 对方法体进行修改或重写。
(2)重载和重写的具体规则
(3)重载: 不表现为多态性 重写: 表现为多态性
(4)重载,是指允许存在多个同名方法,而这些方法的参数不同。编译器根据方法不同的参数表,对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了不同的方法。它们的调用地址在编译期就绑定了。Java的重载是可以包括父类和子类的,即子类可以重载父类的同名不同参数的方法。所以,对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法,这称为 “早绑定”或“静态绑定” ;而对于多态,只等到方法调用的那一刻,解释运行器才会确定所要调用的具体方法,这称为 “晚绑定”或“动态绑定” 。
3、关键字:super
理解为:父类的
3.1、super调用属性、方法:
- 我们可以在子类的方法或构造器中。通过使用"super.属性"或"super.方法"的方式,显式的调用父类中声明的属性或方法。但是,通常情况下,我们习惯省略"super."
- 当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则必须显式的使用"super.属性"的方式,表明调用的是父类中声明的属性。
- 当子类重写了父类中的方法以后,我们想在子类的方法中调用父类中被重写的方法时,则必须显式的使用"super.方法"的方式,表明调用的是父类中被重写的方法。
3.2、super调用构造器:
- 我们可以在子类的构造器中显式的使用"super(形参列表)"的方式,调用父类中声明的指定的构造器。
- "super(形参列表)"的使用,必须声明在子类构造器的首行!
- 我们在类的构造器中,针对于"this(形参列表)"或"super(形参列表)"只能二选一,不能同时出现。
- 在构造器的首行,没显式的声明"this(形参列表)“或"super(形参列表)”,则默认调用的是父类中空参的构造器:super()
- 在类的多个构造器中,至少一个类的构造器中使用了"super(形参列表)",调用父类中的构造器。
4、子类对象实例化全过程
子类中所有的构造函数默认都会访问父类中的空参数的构造函数。当然,如果子类中指定了访问父类带参数的构造函数,就不会访问父类默认的构造函数。所以,如果父类中没有默认的构造函数,子类尝试调用父类的默认构造函数,程序就会报错:
publicclassExtendsDemo{publicstaticvoidmain(String[] args){newZi(10);}}classFu{Fu(int x){//指定了新的构造函数,默认的构造函数就没有了System.out.println("父类有参构造器");}}classZiextendsFu{Zi(){super(3);//父类有带参数的构造函数System.out.println("子类无参构造器");}Zi(int x){this();//super(x); //默认会访问父类的构造函数System.out.println("子类有参构造器");}}
运行结果:
图示:
5、多态性
5.1、什么是多态性?
父类的引用指向子类的对象(或子类的对象赋给父类的引用)
5.2、多态性的使用:虚拟方法调用
有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。
总结:编译,看左边;运行,看右边。
注意点:对象的多态性,只适用于方法,不适用于属性(编译和运行都看左边)
5.3、多态性的使用前提:① 类的继承关系 ② 方法的重写
5.4、关于向上转型(多态)与向下转型:
- 为什么使用向下转型: 有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法的,但是由于变量声明为父类类型,导致编译时,只能调用父类中声明的属性和方法。子类特有的属性和方法不能调用。如何才能调用子类特的属性和方法?使用向下转型。
- 如何实现向下转型: 使用强制类型转换符:()
- 使用时的注意点: ① 使用强转时,可能出现ClassCastException的异常。 ② 为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先进行instanceof的判断,一旦返回true,就进行向下转型。如果返回false,不进行向下转型。
- instanceof的使用: ① a instanceof A:判断对象a是否是类A的实例。如果是,返回true;如果不是,返回false。 ② 如果 a instanceof A返回true,则 a instanceof B也返回true.其中,类B是类A的父类。 ③ 要求a所属的类与类A必须是子类和父类的关系,否则编译错误。
图示:
5.5、多态性的理解:
1、实现代码的通用性
2、Object类中定义的public boolean equals(Object obj){ }
JDBC:使用java程序操作(获取数据库连接、CRUD)数据库(MySQL、Oracle、DB2、SQL Server)
3、 抽象类、接口的使用肯定体现了多态性。(抽象类、接口不能实例化)
6、Object类的使用
6.1、java.lang.Object类的说明:
- Object类是所Java类的根父类
- 如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object类
- Object类中的功能(属性、方法)就具通用性。 属性:无 方法:equals() / toString() / getClass() /hashCode() / clone() / finalize() / wait() / notify() / notifyAll()
- Object类只声明了一个空参的构造器
6.2、equals()方法的使用:
① 是一个方法,而非运算符 ② 只能适用于引用数据类型 ③ 比较两个对象的"实体内容"是否相同。
7、包装类的使用
7.1、为什么要有包装类(或封装类)
为了使基本数据类型的变量具有类的特征,引入包装类。
7.2、基本数据类型与对应的包装类:
7.3、需要掌握的类型间的转换:(基本数据类型、包装类、String)
简易版:
- 基本数据类型<—>包装类: JDK 5.0 新特性:自动装箱 与自动拆箱
- 基本数据类型、包装类—>String: 调用String重载的valueOf(Xxx xxx)
- String—>基本数据类型、包装类: 调用包装类的parseXxx(String s)注意: 转换时,可能会报NumberFormatException
应用场景举例:
- Vector类中关于添加元素,只定义了形参为Object类型的方法: v.addElement(Object obj); //基本数据类型 —>包装类 —>使用多态
版权归原作者 今年别秃头 所有, 如有侵权,请联系我们删除。