目录
Java重要特点
Java运行机制及运行过程
什么是JDK,JRE
配置环境变量path
Java开发注意事项和细节说明
Java转义字符
注释的重要性
DOS命令了解
相对路径和绝对路径
变量
程序中+号的使用
数据类型
运算符
标识符的命名规则和规范
键盘输入语句
进制的转换
原码,反码,补码
顺序控制
循环控制
跳转控制
数组
类与对象
成员方法
IDEA使用
包
访问修饰符
面向对象三大特征
Object类详解
第二阶段
编译性语言,编译后的代码,可以直接被机器执行,c/c++】
配置环境变量path:
Java常用的转义字符:
在控制台,输入tab键,可以实现命令补全
常用的dos命令:
每一种数据都定义了明确的数据类型,在内存中分配了不同大小的内存空间(字节)。
数类型使用细节
浮点类型使用细节
Java API 文档
1.API(Application Programming Interface,应用程序接口)是java提供的基本编程接口,中文在线文档:码工具 - 代码在线工具箱。
2. Java语言提供大量的基础类,因此Oracle公司也为这些基础类提供了相应的API文档,用于告诉开发者如何使用这些类,以及这些类包括的方法。
3.Java类的组织形式【图】
字符类型使用细节
1.字符常量是用单引号(' ')括起来的单个字符,例如:char c1 = 'a';
2. java中还允许使用转义字符'\',来将其后的字符转变为特殊字符型常量。例如:char c2 = '\n';
3. 在java中char本质是一个整数,在输出时,是unicode码对应的字符,用int可以转换对应的整数。
4. 可以直接赋值一个整型变量给字符类型,其输出的则是unicode码对应的字符。
重点例子:char c1 = ‘b’ + 1;
System.out.println(‘b’ + 1);//输出结果为99
System.out.println((int)c5);//输出结果为99
System.out.println(c5);//输出结果为99对应的字符->编码表ASCII
探讨:字符型存储到计算机中,需要将字符对应的码值(整数)找出来。比如‘a’
存储:‘a’è码值97è二进制(1100001)è存储
读取:二进制(1100001)è97è’a’è显示
字符和码值的对应关系是通过字符编码表决定的(规定好的)
常用编码
1.ASCII码介绍:上个世纪60年代,美国制定了一套字符编码(使用有一个字节),对英语字符与二进制位之间的关系,做了统一规定。这被称为ASCII码。ASCII码一共规定了128个字符的编码,只占用了一个字节的后面7位,最前面的1位统一规定为0。(一个字节可以表示256个字符,ASCII码只用了128个字符)。缺点:不能表示所有字符。
2.Unicode编码介绍:Unicode的好处,一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,使用Unicode没有乱码的问题。缺点:一个英文字母和一个汉字都占用2个字节,这对于存储空间来说是浪费。
3.UTF-8编码介绍:UTF-8是在互联网上使用最广的一种编码,它是一种变长的编码方式。可以使用1-6个字节表示一个符号,根据不同的符号而变化字节长度。例如在中国使用,字母占一个字节,汉字占3个字节。
布尔类型:boolean
1.布尔类型也叫boolean类型,boolean类型数据只允许取值true和false,无null。
2.boolean类型占一个字节
3.boolean类型适用于逻辑运算,一般用于对程序流程控制
基本数据类型转换
1.当java程序在进行赋值或者运算时,精度小的类型自动转换为精度大的数据类型,这个就是自动类型转换。
2.数据类型按精度大小排序为(规则):
charèintèlongèfloatèdouble
byteèshortèintèlongèfloatèdouble
细节:1.有多种类型的数据混合运算时,系统首先自动将所有数据转换成容量最大的那种数据类型,然后进行计算。
例子:int n1 = 10;
float d1 = n1 + 1.1;//错误n1 + 1.1 =>结果是double类型
解决方案1.double d1 = n1 + 1.1; 2.float d1 = n1 + 1.1f;
2.当我们把精度大的数据类型赋值给精度小的数据类型时,就会报错,反之就会进行自动类型转换。
3.(byte,short)和char之间不会相互自动转换。
4.把具体数赋值给byte时,编译器会先判断是否在byte范围内(-128~127),如果是就可以。
例子:byte b1 = 10;//对 int n2 = 1; byte b2 = n2;//错,int型4个字节。
5.byte,short,char他们三者可以计算,在计算时首先转换为int类型。
例子:byte b2 = 1; short s1 = 1; //short s2 = b2 + s1;//错,b2 + s1 =>int
byte b1 = 2; byte b3 = b2 + b1;//错误,b2 + b1 =>int
6.boolean不参与转换
7.自动提升原则:表达式结果的类型自动提升为操作数中最大的类型。
例子:byte b4 = 1;
short s3 = 100;
int num = 1;
double num2 = 1.1;
只有这样赋值给double型才正确:double num3 = b4 + s3 + num + num3;
强制类型转换:自动类型转换的逆过程,将容量大的数据类型转换为容量小的数据类型。使用时要加上强制转换符(),但可能造成精度降低或溢出,格外要注意。
例子:int j = 100; byte b1 = (byte)j;
System.out.println(b1);//结果是-48,数据溢出。
int n1 = (int)1.9;
System.out.println(n1);//结果是1,精度损失。
细节:1.强转符号只针对于最近的操作数有效,往往会使用小括号提升优先级。
int x = (int)10 * 3.5 + 6 * 1.5;//编译错误,还是double类型。
2.char类型可以保存int的常量值,但不能保存int的变量值,需要强转。
4.byte和short,char类型在进行运算时,当作int类型处理。
String字符串类型
介绍:在程序开发中,我们经常需要将基本数据类型转成String类型。或者将String类型转成基本数据类型。
1.基本类型转String类型语法:将基本类型的值+“”即可。
int n1 = 100; String s1 = n1 + “”;//这样就转成了字符串类型
2.String类型转基本数据类型语法:通过基本类型的包装类调用parseXX方法即可。
细节1:System.out.println(10 / 4);//结果等于2,因为两个数都是int型,精度损失。
System.out.println(10.0 / 4);结果是2.5。
double d = 10 / 4;//输出的结果是2.0。
细节2:System.out.println(10 % 3);//结果是1(取余数)
System.out.println(-10 % 3);//结果-1
System.out.println(10 % -3);//结果1
System.out.println(-10 % -3);//结果-1
总结:模正负和前面那个数正负有关。
细节3:i++;和++i;作为单独语句时都是自增+1。
在表达式使用中:++i表示先自增后赋值。i++表示先赋值后自增。
int j = 8;
int k = ++j;//等价于 j = j + 1;k = j;
int k = j++;//等价于 k = j;j = j + 1;
关系运算符
位运算符
逻辑运算符
细节1:&&短路与:如果第一个条件为false,则第二个条件不会判断,最终结果为false,效率高。
细节2:&逻辑与:不管第一个条件是否为false,第二个条件都要判断,效率低。
赋值运算符
三元运算符
1.基本语法:条件表达式?表达式1:表达式2;
2.用法:如果条件表达式为true,运算后的结果是表达式1的值。如果条件表达式为false,运算后的结构是表达式2的值
例子:int a = 2; int b = 8; int c = a > b ? a : b;
运算符优先级
优先级从上往下如图所示:
优先级先后顺序:(1)(),{}等è单目运算符è算术运算符è位移运算符è比较运算符è逻辑运算符è三元运算符è赋值运算符。
1.java对各种变量,方法和类等命名时使用的字符序列称为标识符。
2.凡是自己可以起名字的地方都叫标识符。
标识符的命名规则:
(1)由26个英文字母大小写,0到9,_或$组成
(2)数字不可以开头。
(3)不可以使用关键字和保留字,但能包含关键字和保留字
(4)java中严格区分大小写,长度无限制
(5)标识符不能包含空格。
标识符命名规范:
(1)包名:多单词组成时所有字母都小写,如:aaa.bbb.ccc //com.xzc.crm
(2)类名,接口名:多单词组成时,所有单词的首字母大写,如XxxZzzCcc【大驼峰法】
(3)变量名,方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写,如xxxYyyZzz。【小驼峰法】
(4)常量名:所有字母都大写。多单词时每个单词用下划线连接,如XXX_YYY_ZZZ。
1.导入Scanner类:import java.util.Scanner;
2.创建Scanner对象,new创建一个对象:Scanner myScanner = new Scanner(System.in);
3.String name = myScanner.next();
1.二进制转十进制:从最低位(右边)开始,将每个位上的数提取出来,乘以2的(位数-1)次方,然后求和。例如:1011 = 1*2的(1-1)次方+1*2的(2-1)次方+0+1*2的(4-1)次方 = 11
2.八进制转十进制:从最低位开始,将每个位上的数提取出来,乘以8的(位数-1)次方,然后求和。
3.十六进制转十进制:从最低位开始,将每个位上的数提取出来,乘以16的(位数-1)次方,然后求和。
例如:0x23A = 10*16^0+3*16^1+2*16^2
4.十进制转二进制:将该数不断除以2,直到商为0为止,然后将每步得到的余数到过来,就是对应的二进制。例如:34 = 100010
5.十进制转八进制:将该数不断除以8,直到商为0为止,然后将每步得到的余数倒过来就是对应的八进制。
6.十进制转十六进制:将该数不断除以16,直到商为0为止,然后将每步得到的余数倒过来就是对应的八进制。
7.二进制转八进制:从低位开始,将二进制数每三位一组,转成对应的八进制数即可。例如将11010101转成八进制为325.
8.二进制转十六进制:从低位开始,将二进制数每四位一组,转成对应的八进制数即可。
9.八进制转二进制:将八进制数每一位转成对应的一个3位的二进制数即可。
10.十六进制转二进制:将十六进制数每一位转成对应的一个4位的二进制数即可。
1.单分支if
2.双分支if-else
3.多分支if-else if-…-else
4.嵌套分支if(if(if…))
5.switch(表达式){
case 常量1:
语句1;
break;//结束退出switch
……
default: //如果都不匹配就执行default语句
语句;
break;
}
switch注意细节:1.switch中表达式的返回值必须是(byte,short,int,char,enum,String)
2.case子句中的值必须是常量,而不能是变量
3.如果没有写break,程序会顺序执行到结尾。
案例:switch(month){
case 3:
case 4:
case 5:
System.out.println(“这是春季”);
break;
}//表示3,4,5都输出这是春季。
for循环控制
1.for(循环变量初始化;循环条件;循环变量迭代){
循环操作(可以多条语句);
}
先执行循环变量初始化,再判断循环条件,如果是true,执行循环操作语句,然后执行循环变量迭代,然后再判断循环条件,当判断循环条件是false时,循环结束。
while循环
1.基本语法:
循环变量初始化;
while(循环条件){
循环体(语句);
循环变量迭代;
}
do while循环
1.基本语法:
循环变量初始化;
do{
循环体(语句);
循环变量迭代;
}while(循环条件);
先执行再判断,也就是说一定会执行一次。
多重循环
就是循环嵌套,先执行完内部的循环,再跳出,执行外部的循环不断重复,直到外层循环判断为false为止。
跳转控制语句-break
使用在循环中,终止循环
细节:break语句出现在多层嵌套的语句块中时,可以通过标签指明要终止的是哪一层语句块
跳转控制语句-continue
用于结束本次循环,继续执行下一次循环
跳转控制语句-return
使用在方法,表示跳出所在的方法
1.数组的定义:
数据类型 数组名[] = new 数据类型[长度]; 数据类型 数组名[] = {元素1,元素2…};
数组下标从0开始,长度为5的数组下标为0-4。
2.使用细节:
(1)数组是多个相同类型数据的组合。
(2)数组中的元素可以是任何数据类型,包括基本数据类型和引用类型,但不能混在一起用。
(3)数组创建后,如果没有赋值会有默认值。
(4)数组下标从0开始
(5)数组属于引用类型,数组型数据是对象(object);
(6)数组在默认情况下是引用传递,赋的值是地址,赋值方式为引用赋值。例如:
int[] arr1 = {1,2,3};
int[] arr2 = arr1;
arr2[0] = 10;
这样对应的arr1中的第一个元素也会变成10
引用数据类型拷贝的是地址,所以arr1,arr2都能访问数据
二维数组
可以这样理解:原来的一维数组的每个元素是一维数组,就构成二维数组
for(int i = 0;I < arr.length; i++){//遍历二维数组的每个元素
for(int j = 0; j < arr[i].length;j++){//遍历每个元素对应一维数组的元素
System.out.print(arr[i][j]);
}
System.out.print();
}
特殊二维数组:第一行一维数组元素只有1个,第二行一维数组元素有2个,第三行一维数组元素有3个.
int[][] arr = new int[3][];
for(int i = 0;i < arr.length;i++){
arr[i] = new int[i + 1];
//然后下面再给每一个一维数组元素赋值
}
1.类就是数据类型(自定义)
2.对象就是一个具体的实例
3.java最大的特点就是面向对象
对象在内存中存在形式:
类属性的定义
1.属性的定义语法,示例:访问修饰符 属性类型 属性名;
2.属性的定义类型可以为任意类型,包含基本类型或引用类型
3.属性如果不赋值有默认值
java内存的结构分析
1.栈:一般存放基本数据类型(局部变量)
2.堆:存放对象(Cat cat,数组等)
3.方法区:常量池(常量,比如字符串),加载类信息
成员方法定义:访问修饰符 返回值类型 方法名(形参列表){方法体,写要执行的代码};
方法调用机制
方法的优点:1.提高代码的复用性。2.可以将实现的细节封装起来,然后供其他用户来调用即可。
方法递归调用
递归就是方法自己调用自己,每次调用时传入不同的变量,递归有助于编程者解决复杂问题,同时可以让代码变得简洁。
1.递归机制:
递归解决阶乘
public int factorial(int n) {
if(n == 1) {
return 1;
}else {
return factorial(n - 1) * n;
}
}
return哪里调用就返回给哪里
递归重要规则
1.执行一个方法时,就创建一个新的受保护的独立空间(栈空间)
2.方法的局部变量是独立的,不会相互影响,比如上面阶乘的n变量
3.如果方法中使用的是引用类型变量,就会共享该引用类型的数据
4.递归必须向退出递归的条件逼近,否则就是无限递归,会出现(StackOverflowError,死龟)
5.当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕
方法重载
概念:java中允许同一个类中,多个同名方法的存在,但要求形参列表不一致
使用细节:1.方法名必须相同 2.参数列表必须不同(参数类型或个数或顺序,至少有一样不同) 3.返回类型没有要求
可变参数
基本概念:java允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法,就可以通过可变参数实现。
基本语法:访问修饰符 返回类型 方法名(数据类型...形参名)
public int sum(int...nums){
int res = 0;
for(int i = 0; i < nums.length; i++){
res += num[i];
}
return res;
} //使用可变参数时,可以当做数组来使用,即nums可以当作数组
1.可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
2.一个形参列表中只能出现一个可变参数
作用域
1.在java编程中,主要的变量就是成员变量和局部变量
2.局部变量一般是指在成员方法中定义的变量
3.java中作用域的分类:
全局变量:也就是属性,作用域为整个类体
局部变量:也就是除了属性之外的其他变量,作用域为定义它的代码块中
4.全局变量可以不赋值,直接使用,因为有默认值,局部变量必须赋值后才能使用,因为没有默认值。
5.属性和局部变量可以重名,访问时遵循就近原则
构造方法/构造器
1.构造器作用:在创建对象时,就直接对对象的属性进行初始化。
2.基本语法:[修饰符] 方法名(形参列表){方法体;}
3.注意事项:构造器没有返回值,方法名和类名必须一样。
4.一个类可以定义多个不同的构造器,即构造器重载(形参不同)
5.如果程序员没有定义构造器,系统会自动给生成一个默认无参构造器
对象创建流程分析
this关键字
1.概念:java虚拟机会给每个对象分配this,代表当前对象
2.哪个对象调用,this就代表哪个对象
注意细节:this在构造器中访问另外一个构造器时语法
public T(){
this(“jack”,100)//这条语句只能放在第一位,表示访问下面的构造器
System.out.println();
}
public T(String name,int age){
System.out.println();
}
3.this不能在类定义的外部使用,只能在类定义的方法中使用。
public class Test{
public static void main(String[] args){
Person p1 = new Person("牛",18);
Person p2 = new Person("牛",18);
System.out.println(p1.compareTo(p2));
}
}
class Person{
String name;
int age;
public Person(String name,int age) {
this.name = name;
this.age = age;
}
public boolean compareTo(Person p) {
// if(this.name.equals(p.name) && this.age == p.age) {
// return true;
// }else {
// return false;
// }
return this.name.equals(p.name) && this.age == p.age;
}
}
1.快捷键查找:File->Setting->Keymap(可以自己修改快捷键)
2.删除一行代码:Ctrl+D
3.复制一行代码:Ctrl+alt+向下箭头
4.补全代码:alt+/
5.快速格式化代码:Ctrl+alt+L
6.快速运行程序:alt+R
7.生成构造器:alt+insert
8.查看一个类的层级关系:Ctrl+H
9.定位到方法:Ctrl+B
10.自动分配变量名,通过在后面加.var(例如:new Scanner().var)
11.模板/自定义模板:file->setting->editor->Live templates->
包的三大作用
1.区分相同名字的类
2.当类很多时,可以很好的管理类
3.控制访问范围
包的基本语法
1.package 关键字,表示打包
2.例如:com.hspedu:表示包名(com.表示一级目录)。这样创建包名的时候,会产生com文件夹,然后com里面再产生hspedu文件夹。
包的本质
就是创建不同的文件夹来保存类文件
注意事项:同类名的不同包只能导入一个,第二个同名类在使用时,类名前加上包名以此区分。
包的命名规则和规范
1.只能包含数字,字母,下划线,小圆点,但不能用数字开头,不能是关键字或保留字
2.一般是小写字母+小圆点(例如:一般是com.公司名.项目名.业务模块名)
常用包
1.java.lang.* //lang包是基本包,默认引入,不需要再引入
2.java.util.* //util包,系统提供的工具包,工具类
3.java.net.* //网络包,网络开发
4.java.awt.* //是做java界面开发,GUI
如何引入包
1.语法:import 包;
2.例如:import java.util.Scanner;这就只是引用一个Scanner类
3.import java.util.*表示将这个包下所有类都引入
注意事项和使用细节
1.package的作用是声明当前类所在的包,需要放在类的最上面,一个类中最多只有一句package。
2.import指令位置放在package的下面,在类定义前面,可以有多句且没有顺序。
基本介绍
1.公开级别:用public修饰,对外公开
2.受保护级别:用protected修饰,对子类和同一个包中的类公开
3.默认级别:没有修饰符,向同一个包的类公开
4.私有级别:用private修饰,只有类本身可以访问,不对外公开
使用注意事项:只有默认和public才能修饰类
基本介绍
面向对象编程三大特征:封装,继承和多态
封装
1.封装就是把抽象出的数据【属性】和对数据的操作【方法】封装在一起,数据被保护在内部,程序的其他部分只有通过被授权的操作【方法】,才能对数据进行操作。
2.封住隐藏实现细节 方法(很多操作)<---调用
3.可以对数据进行验证,保证安全合理
4.可以在构造器中调用set()方法来限制属性是否合理
public Person(String name, int age, double salary){
//写有限制条件的set方法
setName(name);
setAge(age);
setSalary(salary);
}
继承
1.继承可以解决代码复用问题,让我们的编程更加接近人类思维。当多个类存在相同的属性和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需通过extends来声明继承父类即可。
基本语法:
class 子类 extends 父类{
}
子类就会自动拥有父类定义的属性和方法
继承使用细节:
1.子类继承了所有的属性和方法,但是私有属性和方法不能在子类直接访问,要通过公共方法访问。(就是把父类的私有的属性和方法写到public修饰的方法中去,让子类调用这public方法)
2.子类必须调用父类的构造器,完成父类的初始化。(在子类的构造器中的第一个语句默认有super();它默认去调用父类的无参构造器)
3.当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中使用super去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不通过。(在子类构造器中必须用super(“xxx”,”xxx”);)
4.如果希望指定去调用父类的某个构造器,则显示调用一下:super(参数列表)
5.super在使用时,需要放在构造器第一行
6.super()和this()都只能放在构造器第一行,因此这两个方法不能共存在一个构造器
7.java所以类都是Object类的子类
8.父类构造器的调用不限于直接父类!将一直往上追溯到Object类(顶级父类)
9.子类最多只能继承一个父类,即java中是单继承机制。
10.不能滥用继承,子类和父类之间必须满足is-a的逻辑关系。比如Person is a Music? Cat is Animal
继承的本质
Super关键字
基本介绍:‘
super代表父类的引用,用于访问父类的属性,方法,构造器
基本语法:
1.访问父类的属性super.属性名,但不能访问父类private属性
2. 访问父类的方法super.方法名,但不能访问父类private方法
3.当子类中有和父类的成员(属性和方法)重名时,为了访问父类的成员,必须通过super。
方法重写/覆盖(override)
1.基本介绍:
方法覆盖就是子类有一个方法和父类的某个方法的名称、返回类型、参数一样,那么我们就说子类的这个方法覆盖了父类的那个方法
2.细节注意:
子类的方法的返回值类型和父类方法返回类型一样,或者是父类返回类型的子类
3.子类方法不能缩小父类方法的访问权限
多态
1.基本介绍:
方法或对象具有多种形态。是面向对象的第三大特征,多态建立在封装和继承的基础之上。
2.具体表现:
方法的多态:重写和重载就体现多态
对象多态:
一个对象的编译类型和运行类型可以不一致
编译类型在定义对象时,就确定了,不能改变
运行类型是可以变化的
向上转型
1.本质:父类的引用指向了子类的对象
2.语法:父类 引用名 = new 子类类型();
3.特点:可以调用父类中的所有成员(需遵循访问权限)
不能调用子类中特有成员
最终运行效果看子类的具体实现
向下转型
1.语法:子类类型 引用名=(子类类型)父类引用
2.只能强转父类的引用,不能强转父类的对象
3.要求父类的引用必须指向的是当前目标类型的对象
4.可以调用子类类型所有的成员
Animal animal=new Cat();
Cat cat=(Cat) animal;
5.instanceof比较操作符,用于判断对象的类型是否是XX类型或XX类型的子类型
动态绑定机制
==和equals的对比
1.如果判断基本类型,判断的是值是否相等
2.如果判断引用类型,判断的是地址是否相等,即判定是不是同一个对象、
类变量和类方法
Final关键字
抽象类
接口