1991 年Sun公司的James Gosling等人开始开发名称为 Oak 的语言,希望用于控制嵌入在有线电视交换盒、PDA等的微处理器;
1994年将Oak语言更名为Java;
Java的三种技术架构:
JAVAEE:Java Platform Enterprise Edition,开发企业环境下的应用程序,主要针对web程序开发;
JAVASE:Java Platform Standard Edition,完成桌面应用程序的开发,是其它两者的基础;
JAVAME:Java Platform Micro Edition,开发电子消费产品和嵌入式设备,如手机中的程序;
1,JDK:Java Development Kit,java的开发和运行环境,java的开发工具和jre。
2,JRE:Java Runtime Environment,java程序的运行环境,java运行的所需的类库+JVM(java虚拟机)。
3,配置环境变量:让java jdk\bin目录下的工具,可以在任意目录下运行,原因是,将该工具所在目录告诉了系统,当使用该工具时,由系统帮我们去找指定的目录。
程序执行需要使用外部指令javac,但是javac指令只能在JDK安装目录下的 bin目录执行,path环境变量使javac指令在任意目录下都可以运行
1.在系统环境中新建JAVA_HOME,把JDK的安装路径复制进去
2. 在path最上方添加%JAVA_HOME%\bin ————%%作用相当于引用
被java语言赋予特定含义的单词
全部小写
1.goto和const作为保留字存在
2.类似Notepad++这样的高级记事本会对关键字有特殊颜色标记
标识符就是给包、变量、常量、类名、方法、接口命名
1.英文字母大小写
2.数字
3.$和_
1.不能以数字开头
2.不能是java中的关键字
3.区分大小写
1.包 全部小写
1.单级包:小写
举例:back
2.多级包:小写,并用.隔开
举例:cn.itcast``
2.类和接口
1.一个单词:首字母大写
举例:Student
2.多个单词
举例:StudentName
3.方法名或变量名
1.一个单词:首字母小写
举例:name
2.多个单词:从第二个单词开始,每个单词首字母大写
举例:studentAge
4.常量
1.全部大写
2.一个单词:大写
举例PI
3.多个单词:大写,并用_隔开
举例:STUDENT_MAX_AGE
就是对程序进行解释说明的文字
1.单行注释://
2.多行注释:/**/
3.文档注释:/** */
后面我们要写一个程序的过程
需求:
分析:
实现:
代码体现:
1.解释说明程序,提高了代码的阅读性
2.可以帮助我们调试程序
在程序执行的过程中,其值不发生改变的量
1.字面值常量
2.自定义常量
1.字符串常量
2.整数常量
3.小数常量
4.字符常量
5.布尔常量
6.空常量:null
1.二进制:由0,1组成。以0b开头
2.八进制:由0,1,.....7组成。以0开头
3.十进制:由0,...9组成。整数默认是十进制
4.十六进制:由0,..9,a,b,c,d,e,f(大小均可)组成。以0x开头
在程序的执行过程中,其值在某个范围内可以发送改变的量
1.数据类型 变量名 = 初始化值;
2. 数据类型 变量名;
变量名 = 初始化值;
变量实例化之后才有默认值,比如:new Student().age 默认值为0
没有实例化就没有值,需要赋值才行
比如:int a=10;
java是一种强类型语言,针对每种数据都提供了对应的数据类型
1.整数默认是int类型,浮点数默认是double
2.定义long类型时要加L
3.定义float类型时要加F
4.byte,short在定义的时候,他们接收的其实是一个int类型的值,这个是自己做了一个数据检测的,如果不在他们的范围内,就报错
1. 从大到小
2. byte,short,char--int--long--float--double
3. byte,short,char之间不相互转换,直接转成int类型参与运算
4. long:4字节
float:8字节
为什么long 要转换成float呢?
1. 因为他们的底层存储结构不同
2. float表示的数据范围比long的范围要大
long:2^63-1
float:3.4*10^38>2*2^114
1.从大到下
2.可能会有精度损失,一般不建议这样使用
3.格式
1. 目标数据类型 变量名 = (目标数据类型)(被转换的数据);
4.思考题和面试题
1. 下面两种方式有区别吗?
float f1 = 12.345F;
float f1 = (float)12.345; ——可能会有精度缺失,浮点默认为double
2. 面试题
一、
答: byte b1=3.b2=4,b;
b=b1+b2; //报错,b1+b2先类型提升到int,所以值是int,精度会缺失
b=3+4 //真确,先算计算结果得7,然后看结果是否在byte的范围内,如果在就不报错
//有问题,因为byte是1字节范围是-128~127,130不在这个范围
//正确做法
byte b = (byte)130;
//计算机中的数据运算都是用补码进行的,首先要先算出130的二进制
//整数是4字节,所以130原码是00000000 00000000 00000000 10000010
//正数的原,反,补都一样,然后做截取操作,截成byte--10000010
//这个结果是补码,需要转化成原码----1 1111110 = -126
——三、 byte值问题
byte b1 = 127;
byte b2 = (byte)128; //-128
byte b3 = (byte)129; //-127
byte b4 = (byte)130; //-126
byte的范围:-128~127
128:10000000
-128:10000000(这里的1即是符号位,也是数值位)
5.ASCII码 —— 字符和整数计算时,字符转为ASCII码数字
'0'——48
'a'——97
'A'——65
字符串和其他数据做+,结果是字符串类型。这里的+不是加法运算,而是字符串连接符
System.out.println("hello"+'a'+1) //helloa1
System.out.println('a'+1+"hello") //98hello
1. +,-,*,/,%,++,--
2. +的用法
1.加法
2. 正号
3. 字符串连接符
3./和%的区别
1.数据做除法操作的时候,/取商,%取余
2. /取商时候,如果一个数有小数,那么结果就是小数
4.++和--的用法
1. 单独使用
1.放在操作数据的前面和后面效果一样:a++或者++a效果一样
2. 参与操作使用
1. 放在操作数的前面:先自增或自减,在参与操作
int b=++a;
2. 放在操作数后面:先参与操作,再自增或者自减
int b =a++;
3.例题:
int x=4;
int y=(x++)+(++x)+(x*10);
//4+6+60
//x=5,6
1.=,+=,-=,*=,/=,%=等
2.扩展的赋值运算符的特点
1.隐含了自动强制转换
2.面试题:
第一个有问题,因为s+1的值是int类型,而是short会出现精度丢失
第二个没问题,因为扩展的赋值运算符其实隐含了一个强制类型的转换
s+=1;
不是等于s=s+1;而是等于s=(s的数据类型)(s+1)
+= 有追加的意思,在原先的基础上追加
1. ==,!=,>,<,<=,>=
2. 逻辑运算符用于连接boolean类型的式子
3. 结论
1. &:有false则false,两边都为true,结果才为true
2. |:有true则true
3. .^( 异或):相同则flase,不同则true
情侣关系
4.!:非true则flase,非flase则true
5.&&:结果和 & 一样,只不过有短路效果。左边是flase,右边不执行。(提高了运行效率)
6.||:结果和 | 一样,只不过有短路效果。左边是true,右边不执行。(提高了运行效率)
计算机底层都是位运算,要做位运算,首先要把数据转换为二进制
2.
^的特殊用法:一个数据针对另一个数据位异或两次,该数不变
1. 面试题:
一、请自己实现两个整数变量的交换
二、
一般思想是 2*8,但是这不是最有效率的,乘法或者除法在底层都是转成位移
答案:2 << 3
一、<< 把左边的数据乘以2的移动次幂(在右边补0)
3 << 2 // 3 * 2 ^ 2 = 3 * 4 = 12
二、>> 把左边的数据除以2的移动次幂 (如果是负数则在左边补1)
24 >> 2 // 24 / 2 ^ 2 = 24 / 4 = 6
三、24>>>2 (无论正负都在左边补0)
5.逻辑运算符和位运算符很像,当两边是boolean值是表示逻辑运算符(x<3 & x<5),当两边是数字则表示的是位运算符(3 & 4)
1. 格式:比较表达式?表达式1:表达式2
2. 案例:
1. 获取两个数据中的最大值
2. 获取三个数据中的最大值
int max = (a>=b)?a:b;
int Max = (max>=c)?max:c;
System.out.println(Max);
3. 例子,判断是否是闰年
System.out.println((x% 4 == 0 && x % 100 != 0) || (x% 400 == 0)? "输入的是闰年!" : "输入的不是闰年!");
1. 导包(import java.uyil.Scanner;)
2. Scanner sc = new Scanner(System.in);
3. int x = sc.nextInt();
next()方法读取到空白符就结束l;
nextLine()读取到回车结束也就是“\r”;
所以没还顺序前测试的时候next()再检测的空格的时候就结束输出了。
1. 顺序结构
2. 选择结构:按照不同的选择,执行不同的代码
3. 循环结构:做一些重复的代码
2.if(比较表达式);一般来说,有左大括号,就没有分号,有分号就没有左大括号
3.在做一个程序的基本测试时,一定要考虑(正确数据、错误数据、边界数据)
1. 所有三元运算符能实现的,if语句都能实现
2. 如果if语句语句体部分是输出语句system.out.print则三元不能实现,三元运算符是一个运算符,必须要有一个结果返回,不能是一个输出
switch(表达式){
case 值1:
语句体1;
break;
case 值2:
语句体2;
break;
default:
语句体n;
break;;
}
1.表达式:可以是byte,short,int,char
JdK5以后可以是枚举
Jdk7以后可以是字符串
case:后面的值就是要和表达式进行比较的值
break:表示程序到这里中断,跳出switch语句
default:如果所有的情况都不匹配,就执行这里,相当于if语句的else
2. 面试题
switch语句的表达式可以是byte吗?可以是long吗?可以是String吗?
可以,jkd7以后可以用
1.case后面只能是常量,数字,字符,字符串都行
2.default可以省略吗?
可以,但不建议,它的作用是对不正确的情况给出提示,特殊情况:case就能把值固定A,B,C,D
3.break可以省略吗?
可以省略,但是结果不是我们要的,会出现一个现象:case穿透,有时候我们会用到case穿透
4.default不一定要在最后,可以在任意位置
5.switch语句的结束条件
1.遇到break就结束
2.执行到末尾就结束
1. if
1.针对boolean类型的判断
2.针对一个范围的判断
3.针对一个范围的判断
2.switch
1.针对几个常量的判断
诀窍,一次只看一个for,不要好几个for一起看,当看一个for的时候,就把其他的for循环当做不存在
2.水仙花是指一个三位数,其个位十位百位上的立方和等于他本身
for(int x=1;x<=4;x++){
for(int y=1;y<=5;y++){
System.out.print("*"); //print,不换行,横着输出
}
System.out.println(); //输出空语句来实现换行
for(int x=1;x<=4;x++){
for(int y=1;y<=x;y++){
System.out.print("*"); //几行输出几列
}
System.out.println(); //输出空语句来实现换行
}
for(int x = 1;x<=9;x++){ //行只是控制多少行,没有输出
for(int y=1;y<=x;y++){
System.out.print(y+"*"+x+"="+(y*x)+"\t");//列控制输出什么内容
}
System.out.println()
}
6.给数组排序
int[] a={4,6,8,9,2};
for(int y=0;y<a.length;y++){
for(int x=y+1;x<a.length;x++){
if(a[x]<a[y]){ //把a[0]和所有的数比一遍,把最小的给a[0]
int temp=a[y]; //a[1]同理
a[y]=a[x];
a[x]=temp;
}
}
}
for(int x:a){
System.out.print(x);
}
for和while是判断以后在++,而do..while是++以后再判断
1、跳出外层循环
1.用在循环语句中,离开此应用场景无意义
2.作用:跳出单层循环的一次,可以继续下一次
3.continue也可以像break一样,指定哪个循环
1.用于结束离它最近的一个方法,一旦遇到return,程序就不会继续往后执行
1、方法就是完成特定功能的代码块
1.注意:在很多语言中有函数的定义,而在java中,函数被称为方法
注意:传参的时候,要按方法中参数的顺序来赋值,形参中起决定作用的是数据类型,和后面的变量名一点关系没有
为什么和返回值类型无关呢?,因为我们调用方法的时候可以选择不接收返回值,只是执行方法比如 sum(),接收返回值就是 int a =sum(),如果两个方法返回值不一样,其他都一样,但是我调用的时候都不接收返回值,那么根本就无法区分这两个方法,所以重载和返回值无关
public static int sum(int a,int b){
return a+b;
}
public static int sum(int a,int b,int c){
return a+b+c;
}
public static int sum(int a,float b){
return a+b;
}
public static int sum(float b,int a){
return a+b;
}
2.
3.创建对象就是调用构造方法,要是不想让他创建对象,就把方法里的构造方法私有
父类私有是被继承的。但是子类无法访问父类的私有属性或方法,子类继承是继承父类的所有东西除了构造函数。
继承是为了更好的提高代码的重用性,封装则保护了代码的不可见部分,私有继承了但是无法在子类中直接访问 ,可以通过间接的方法,比如调用父类中继承的get()就能访问到父类被私有的实例变量
[外链图片转存失败,源站可能有防盗在这里插入!链机制,建描述]议将图片上https://传(imblog.gnim-.cn/20200527VCKm175647542.png?1)(https://img-blogcsdnimg.cn/20200527175647542.png?)]
This和super都不能在main()方法中使用。因为main()方法是静态的,this是本类对象的引用,静态先于对象,所以是不能使用的。this通常指当前对象,super则指父类的。
1.基本数据类型
返回值是基本数据类型,子类重写时的返回值类型必须和父类一致
2.
内部类是private修饰:
外部类不能被静态修饰
内部类是static修饰:
匿名对象用完就会回收,而堆里面的对象要等垃圾处理器有空了才会回收,匿名对象大大提高了效率
Student s =new Student()
System.out.println(s);//返回地址值
打印出来 什么 那要看你s的toString()
方法是怎么实现的,如果没有toString()方法,那s会默认继承Object的toString()方法,而Object的toString()方法的实现就是返回对象的地址值
String a =new String();
System.out.println(a);
//返回空
因为String类同样也继承了Object,但是String类重写了Object的toString()方法,重写的目的就是返回字符串值本身,而非地址值。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200602151037868.png?
这种方法浪费了大量的字符串空间,后面的StringBuffer方法能改进
StringBuffer就相当于水杯
String与StringBuffer的区别
简单地说,就是一个变量和常量的关系。StringBuffer对象的内容可以修改;而String对象一旦产生后就不可以被修改,重新赋值其实是两个对象。
arr.length-1—x是为了减少比较次数
之后进行遍历即可
前提是数组是有序的,数组无序用基本查找法
Integer 类在对象中包装了一个基本类型
int 的值。Integer 类型的对象包含一个 int 类型的字段。
此外,该类提供了多个方法,能在 int 类型和 String 类型之间互相转换,还提供了处理 int 类型时非常有用的其他一些常量和方法。
注意Integer.parseInt(“123”,2),会报错,因为2进制只有0和1,其他进制也要按规则来
Character 类在对象中包装一个基本类型 char 的值。Character 类型的对象包含类型为 char 的单个字段。
此外,该类提供了几种方法,以确定字符的类别(小写字母,数字,等等),并将字符从大写转换成小写,反之亦然。
就是符合一定规则字符串
用于数字运算的类
public static void exit(int status);
public static long currentTimeMillis()
但是这样单个输出没有意义,我们用于统计程序执行的时间
public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length) {}
参数:
src - 源数组。
srcPos - 源数组中的起始位置。
dest - 目标数组。
destPos - 目标数据中的起始位置。
length - 要复制的数组元素的数量。
从arr的1号元素开始,复制两个元素到从arr2的2号元素开始,就是把8,9替换成了22,33
Date(long date):分配 Date 对象并初始化此对象,以表示自从标准基准时间(称为“历元(epoch)”,即 1970 年 1 月 1 日 00:00:00 GMT)以来的指定毫秒数。
DateFormat针对日期进行格式化和针对字符串进行解析的类,但是是抽象类,所以使用其子类SimpleDateFormat
日历类,封装了所有的日历字段值,通过统一方法根据传入不同的日历字段可以获取值
数组既可以存储基本数据类型,也可以存储引用类型。它存储引用类型的时候数组就叫做对象数组
List集合特点:有序的(存储和取出一致),可重复的
List的列表迭代器是继承了Iterator迭代器,他有更多的功能
没有输出,因为必须先正向遍历才能逆向遍历
方法一:迭代器迭代元素,迭代器修改元素
而Iterator迭代器没有添加功能,所以我们使用其子类接口ListIterator
要保证唯一性,只需要自动导入对象类中的hashCode()和equals()方法即可
TreeSet的无参构造,是自然排序,需要在自定义对象类中重写compareTo()
一、产生10个1-20之间的随机数要求不重复
方法一、根据键找值(推荐)
方法二、根据键值对对象找键和值
遍历图解
哈希表的作用是用来保证键的唯一性
键值是String,String
唯一的,无序的
键值是Integer,String
键值是Integer,String
键值是String,Student
键值是Student,string
为了保证唯一性,需要在student类中自动导入hashCode()和equals()
唯一,实现排序
键值是Student,String
先遍历大集合,再在里面遍历小集合,一层一层来,嵌套别的集合也是一样,比如ArrayList…
ArrayList可以实现HashSet的唯一和TreeSet的排序
两个小问题:
A:多个对象共享一个成员变量,用静态
B:循环里如果有switch,并且在switch里面有break,那么结束的不是循环,而是switch语句
自动拆装箱,泛型增强for,静态导入,可变参数,枚举
一般在集合中使用
泛型是一种把明确类型工作推迟到创建对象或者调用方法的时候才去明确特殊的类型
arrat.add(“hello“);
arrat.add(10); 一开始没有报错,但是程序运行时报错了
所以我们需要确定集合的类型,这就用到了泛型
2.? extends E
增强for其实就是用来代替迭代器的
不能添加和删除,只能修改,因为数组的长度是固定的
JDK7新特性
try括号中的流会自动关闭
如果你创建文件或文件夹没写盘符,那么默认创建在当前项目路径下
ListFiles()功能创建的File数组,之后直接调用File的方法
用的list()方法
一次读取一个字节
读取中文相当于是两个字节的拼接
读取的结果是Acall码,之后强转为char类型还原
无法读取中文。因为中文是两个字节拼接,而它一次只能读取一个字节
一次读取一个字节数组
每次可以读取多个数据,提高了效率
能读取中文,因为一次能读取多个字节
字符流
每个都当一个字符
括号里面是字节流
readLine()读不到换行符,换行要自己写
目的地:复制到哪里
为什么用字符缓冲区
BufferedReader的子类
之前学的都是对字符串的读写
而这个可以对基本数据类型进行读写
不走文件,和集合的存储类似
这里只写字节数组,其他的字符数组和字符串同理
只有写功能
底层也是一个高效流
PrintWriter字符打印流
PrintWriter自动刷新
输出语句的本质就是IO流
第三种:通过字符缓冲流包装标准输入流实现,是第二种没出来之前使用的输入方法
Store()方法 集合数据—>文本文件
文件中的数据必须是键值对
比如迅雷,迅雷本身启动是个进程,但是里面能同时进行多个下载,就是多线程
并行:是逻辑上同时发生,指在某一个时间段内同时运行多个程序
并发:是物理上同时发生,指在某一个时间点同时运行多个程序
Stop()后面的代码不会再执行
Interrupt()会走catch中的代码,和后面的代码
加入sleep()方法后,导致t1,t2,t3会同时进入程序
这些方法调用,必须通过锁对象调用,而我们使用的锁对象是任意锁对象,所以这些方法必须定义在object类中
定义手机规则接口
定义具体手机
定义装饰功能抽象类
具体的听彩铃功能
具体的听音乐功能
测试类
适配器类,空实现接口
把从通到中读出来的数据写入文本文件
通过字节码文件对象去使用,成员变量,构造方法,成员方法
反射前的做法,需要创建对象并调用方法,每有一个对象都得单独创建
每次改需求都得改变代码,太麻烦
反射后的做法,把对象和方法写在配置文件中,用反射来创建对象和方法,改需求的时候只需要改配置文件中的东西就行
通过反射写一个通用的设置某个对象的某个属实为指定的值
工具类
给基本实现添加权限校验
通过动态代理就不用在每一个实现上添加权限校验代码,大大减少了代码修改
具体的代码编写