JAVA_SE
注释
生成API文档指令
javac -encoding UTF-8 -charset UTF-8 [java文件] #修改编码和字符集为了防止中文乱码
标识符
- 只能以字母,$,_ 作为首字母
- 对大小写敏感
- 不能用关键字做变量名或方法名
数据类型
强类型语言:要求变量的使用要严格符合规定,所有变量必须先定义后使用
弱类型语言:与以上相反
c++,c是弱类型语言,在语法上是强类型语言,python是强类型语言
基本类型:整数类型(byte,short,int,long),浮点类型(float,double),字符类型,布尔类型
引用类型:类,接口,数组
//整数类型
int num1=10;
byte num2=20;
short num3=30;
long num4=40L;//long类型要加L
//浮点数
float num5=50.1F;//float类型要加F
double num4=3.13159257855334094;
//字符
char name='a';
//String 是类不是基本数据类型
//布尔类型
boolean flag=true;
boolean flag=false;
//整数拓展:进制 二进制0b,八进制0,十六进制0x
int i=0b1;
int i1=010;
int i2=0x100;
///浮点数拓展 浮点数长度有限,且小数部分是离散的,只能表示接近数,所以在进行浮点数比较时出现貌似相等却不等,貌似不等却相等的问题
//字符拓展
//所有字符本质是数字,unicode编码,两字节 0-65536
//转义字符
\t,\n
类型转换
int i=128;
byte b=(byte)i; //内存溢出,超出类型 容量
//强制转换 (类型)变量名 高->低
//自动转换 低->高
/**
1.不能对布尔值进行转换
2.不能把对象类型转换为不相干的类型
3。把高容量转化到低容量强制转换
4。转换的时候可能存在内存溢出或者精度问题
5.运算中先进行类型转换再运算
*/
System.out.println((int)11.2); //11
System.out.println((int)-11.2f); //-11
变量
java是强类型语言,每个变量必须先声明类型
变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域
作用域
- 类变量:通过static定义
- 实例变量:定义在方法的外面,类里面,从属于对象;如果不进行初始化那么初始化为这个类型的默认值(数值型: 0,0.0;boolean:false;char:u0000;除了基本类型其余的引用类型都是null)
- 局部变量:定义在方法内
常量
初始化后不能再改变值,不会变动的量,通过final定义
常量名一般使用大写字符
对于定义的变量 例如:public static final double PI=3.14;doublee前面的修饰符顺序无关不存在先后顺序
变量的命名规范:
- 所有的变量、方法、类名:见名知义
- 类成员变量:首字母小写和驼峰原则:monthSalary
- 局部变量:首字母小写和驼峰原则
- 常量:大写字母和下户线:MAX_VALUE
- 类名:首字母大写和驼峰原则:GoodBoy
- 方法名:首字母小写和驼峰原则:ranRan()
运算符
- 字符串连接符+
int a=2,b=4;
System.out.println(" "+a+b);// 2,4
System.out.println(a+b+" ");//6
IDEA复制当前行到下一行快捷键ctrl+D
public class test1 {
public static void main(String[] args) {
long a=1234542532532432L;
int b=1234;
short c= 12;
byte d=32;
//该位置整形提升,所有short,byte能够被int容纳的都会转换成int类型
System.out.println(a+b+c+d);//long
System.out.println(b+c+d);//int
System.out.println(c+d);//int
}
}
运算符优先级
一共有十五个优先级:
1 () [] . ->
2 ! ~ -(负号) ++ – &(取变量地址)* (type)(强制类型) sizeof
3 * / %
4 + -
5 >> <<
6 > >= < <=
7 == !=
8 &
9 ^
10 |
11 &&
12 ||
13 ?:
14 = += -= *= /= %= |= ^= &= >>= <<=
15 ,
包机制
为了更好的组织类(如同文件夹),用于区别类名的命名空间
语法格式:package pkg1[.pkg2[.pkg3]]
一般用公司域名导致作包名
导入包
语法格式:import pkg1[.pkg2[.pkg3]]
通配符,导入包下所有类*
Scanner对象
hasNext(),next()
-
读取到有效字符后可以结束输入
-
对输入有效字符之前遇到的空白,next()方法自动将其去掉
-
只有输入有效字符后才将其后面输入的空白作为分隔符或结束符
-
next()不能得到带有空格的字符串
public static void main(String[] args) {
//创建Scanner对象,用于接受键盘输入
Scanner scanner=new Scanner(System.in);
System.out.println("使用next方法接受:");
//判断用户有没有输入字符串
if (scanner.hasNext()){
String str=scanner.next();
System.out.println("输入的 内容:"+str);
}
//凡是属于IO的类如果不关闭会一直占用资源,所以用完要关掉
scanner.close();
使用next方法接受:
Hello world!
输入的内容:Hello
hasnextLine,nextLine()
- 以Enter为结束符,返回输入回车之前的所有字符
- 可以获得空白符
public static void main(String[] args) {
//创建Scanner对象,用于接受键盘输入
Scanner scanner =new Scanner(System.in);
System.out.println("用户输入:");
if (scanner.hasNextLine()){
String str=scanner.nextLine();
System.out.println("用户输入为:"+str);
}
scanner.close();
用户输入:
Hello World!
用户输入为: Hello World!
hasNext()跟hasNextLine()用来获取用户输入,返回值是true,常用在next()跟nextLine()前判断是否有输入数据,;next()跟nextLine()返回输入值
相应的还有获取各种类型输入的方法,hasNextInt,hasNextFloat…返回true或false
nextInt,nextFloat…返回相应类型值
顺序结构
选择结构
if单选择结构
if(//布尔表达式){
//表达式为真要执行的语句块;
}
if双选择结构
if(//布尔表达式){
//表达式为真要执行的语句块;
}else{
//表达式为假要执行的语句块;
}
if多选择结构
if(//布尔表达式1){
//表达式1为真要执行的语句块;
}else if(//布尔表达式2){
//表达式2为真要执行的语句块
}else if(//布尔表达式3){
//表达式3为真要执行的语句块
}else{
//以上表达式均为假要执行的语句块;
}
嵌套的if结构
if(//布尔表达式){
//表达式为真要执行的语句块;
if(//布尔表达式1){
//表达式1为真要执行的语句块;
}else{
//表达式1为假要执行的语句块;
}
}else{
//表达式为假要执行的语句块;
}
switch多选择结构
swich(expression){
case value:
//语句
break;//不加入break将发生穿透现象,之后的case下语句都会执行
case value1:
//语句
break;
default:
//语句
}
IDEA反编译
即将.class字节码文件转化为java文件,(将对应的.class文件在IDEA中打开)
循环结构
while循环
while(布尔表达式){
//循环内容
}
do…while循环
do{
//循环内容
}while(布尔表达式)
for循环
for(初始化控制变量;布尔表达式;变量更新){
// 循环语句
}
增强for循环
for(声明语句:表达式){
//循环语句
}
break;continue
break:跳出循环
continue:终止某次循环,重新验证循环条件
goto保留字
跳转到指定label
java方法
方法:语句的集合,用来执行一个功能
方法的定义
方法包含一个方法头和一个方法体,一个方法由以下部分组成:
- 修饰符
- 返回值类型
- 方法名
- 参数类型
- 方法体
修饰符 返回值类型 函数名(参数){
函数体
return 返回值
}
方法的重载
重载函数就是在一个类中有相同的函数名称,单形参不同的函数
重载规则:
- 方法名称必须相同
- 参数列表必须不同(个数不同,或类型不同,参数的排列顺序不同等)
- 方法的返回类型可以相同也可以不同,仅返回类型不同不足以成为方法的重载
命令行传参
有时候希望循行一个程序的时候再传递给他消息。这要靠命令行参数给main()函数实现。
javac编译不需要退回到包一级,java执行要写全包名
可变参数
-
jdk1.5之后,java支持传递同类型的可变参数给一个方法
-
在方法声明中,再指定类型后加一个省略号(…)
-
一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何不同参数必须再它之前声明。
递归
函数调用本身称为递归调用
递归会占用栈空间使得效率降低
值传递&&引用传递
数组
- 相同类型数据的游戏集合
- 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成;
- 每一个数据称作一个数组元素,每个数组元素可以通过一个下表来访问他们
数组的声明创建
//声明
dataType[] arrayRefVar// 首选的方法
或
dataType[] arrayRefVar[];//效果相同但不是首选
//创建
dataType[] arrayRefVar=new dataType[arraySize];
//数组通过索引访问
//获取数组长度:array.length()
内存分析
数组的三种初始化方式
//静态初始化:
int[] a={1,2,3,4,5};
//动态初始化:包含默认初始化
int []a=new int[2];
a[0]=1;
a[1]=2;
//默认初始化:数组是引用类型,他的元素相当于类的实例变量,因此已经分配孔径,其中的每个元素也被按照实例变量同样的方式被隐式初始化
数组的四个基本特点
- 长度是确定的。一旦创建不可改变大小
- 元素必须是相同类型,不允许出现混合类型
- 数组中的元素可以实任何数据类型,包括基本类型和引用类型
- 数组变量属于引用类型,数组也可以看成是对象,数组中的元素相当于该对象的成员变量。数组本身就是对象,java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组本身是在堆中的
数组的使用
- 普通for循环
- for-each循环
- 数组作为方法参数
- 数组作为返回值
多维数组
格式:int[] [] name=new [] [];
Arrays 类
数组的工具类java.util.Arrays
常用的:
-
Array.fill(),填充
-
Arrays.toString(),返回数组的元素列表
-
Arrays.sort(),升序排序
-
Arrays.equals(),比较元素值是否相等
-
Arrays.binarySearch(),二分查找
稀疏数组
当一个数组中大部分元素为0,或者为同一值的数组时,可以用稀疏数组来保存该数组。
处理方式(用一个数组通过三元组表示):
- 记录数组一共有几行几列,有多少个不同值
- 把具有不同值的元素和行列及值记录在一个小规模数组中,从而缩小程序的规模
面向对象
面向过程思想:
- 步骤清晰简单,一步步执行
- 适合处理过程简单的问题
面向对象思想:
- 分类的思维模式,首先考虑解决问题需要那些分类,然后对这些分类进行单独思考。最后,才对某个特定类下的细节进行面向过程的思索
- 面向对象适合处理复杂的问题,适合处理需要多人协作的问题
对于复杂问题,宏观上面向对象,微观上仍面向过程去处理
本质:以类的方式组织代码,以对象的组织封装数据
三大特性:封装,继承,多态
创建与初始化对象
1.使用new关键字创建对象
- 使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器调用
- Idea快捷键,alt+空格+回车(两下)
2.构造器(主要用来初始化实例对象)
构造器也成为构造方法,是在进行创建对象的售后必须嗲用的,且构造器有以下两个特点
- 必须和类的名字相同
- 必须没有返回类型,也不能写void
Idear生成构造器的快捷键alt+insert
内存分析
-
程序编译首先加载类模板和静态方法
-
main函数压栈,程序开始执行
-
创建对象,将对象内容加载到堆中存储,对象引用保存在栈中
-
程序不断地进行类似压栈出栈操作,直至main执行结束弹出,程序执行完毕
封装
程序设计要追求“高内聚,低耦合”。高内聚是指类的内部数据操作自己完成,不允许外部干涉;低耦合指仅暴露少量方法给外部使用
通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,称为信息隐藏(封装)
主要作用:
- 提高程序的安全性,保护数据
- 隐藏代码的实现细节
- 统一接口
- 增加系统的可维护性
继承
-
extends是继承的关键字,子类继承自父类
-
JAVA中只有单继承没有多继承
-
继承是类和类之间的一种关系,除此之外,类和类之间的关系还有以来、组合、聚合等
//继承 public Student extends Person{ } //组合 public Student{ Person person; } //聚合 public Student{ Computer com; } //处于聚合关系的两个类生命周期不同步,则是聚合关系;处于组合关系的两个类的生命周期同步
-
继承关系的两个类,一个为子类(派生类),一个为父类(基类)。
-
子类和父类之间,从意义上将应该具有“is a”的关系
四种权限修饰符
- public 允许跨类跨包访问
- protected 允许跨包不允许跨类访问
- default 不允许跨包不允许跨类访问
- private 只允许该类对象访问
Java中所有的类直接或间接继承自Object类
子类对象会继承父类所有非私有成员
super
super用来调用父类成员,this调用该对象的成员
注意点:
- super调用父类的构造方法,必须在构造方法第一行执行
- super必须只能出现在子类的方法或构造方法中
- super和this不能同时调用构造方法
创建子类对象会自动调用父类的无参构造函数,如果父类中实现了有参构造函数,无参构造函数就没有了,此时子类对象无法创建程序报错。所以父类中实现有参构造函数后要创建无参构造函数或者在子类中调用有参
方法重写(子类重新实现父类方法)
@Override//注解:有功能的注释
重写只作用于方法,且仅针对非静态方法,对于静态方法
不能重写的方法:static,private,final
//对于非静态方法,可用子类构造方法返回父类对象,该对象调用重写的方法时调用子类的方法
public class javaSE {
public static void main(String[] args) {
Person stu=new Student();
stu.test();
Student stu1=new Student();
stu1.test();
}
}
public class Person {
public void test(){
System.out.println("父类test");
}
}
public class Student extends Person{
public void test(){
System.out.println("子类test");
}
}
子类test
子类test
//对于静态方法,可用子类构造方法返回父类对象,该对象调用重写的方法时调用父类的方法
//对于这两种现象的解释是静态方法在编译加载类模板时静态方法就加载了
public class javaSE {
public static void main(String[] args) {
Person stu=new Student();
stu.test();
Student stu1=new Student();
stu1.test();
}
}
public class Person {
public static void test(){
System.out.println("父类test");
}
}
public class Student extends Person{
public static void test(){
System.out.println("子类test");
}
}
父类test
子类test
重写:需要有继承关系,子类重写父类的方法!
- 方法名必须相同
- 参数列表必须相同(区别于重载)
- 修饰符:范围可以扩大,但不可以缩小 public->protected->default->private
- 抛出的异常:范围可以被缩小,但不能被扩大
为什么重写:父类的方法子类不一定需要或者不一定满足
多态
指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式
- 可以实现动态编译:对象的类型在执行时确定
- 同一方法可以根据发送对象的不同而采用多种不同的行为方式。
- 一个对象的实际类型是确定的,但可以只想对象的引用类型有很多
注意事项:
- 多态是方法的多态,属性没有多态
- 有父子类关系,否则出现类型转换异常:ClassCastException
- 存在的条件:继承关系,方法需要重写,父类引用指向子类对象
方法的重写、重载与动态连接构成多态性。
动态连接:当父类中的一个方法只有在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用; 对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接。
instanceof
用于返回一个对象是不是一个特定类或其子类的实例
Object object=new Student();
System.out.println(object instanceof Person);
System.out.println(object instanceof Object);
System.out.println(object instanceof Student)//true;
System.out.println(object instanceof Teacher);//false
System.out.println(object instanceof String);//false
Person person =new Student();
System.out.println(person instanceof Person);//true
System.out.println(person instanceof Object);//true
System.out.println(person instanceof Student);//true
System.out.println(person instanceof Teacher);;//false
System.out.println(person instanceof String);//语法错误
Student student =new Student();
System.out.println(student instanceof Person);//true
System.out.println(student instanceof Object);//true
System.out.println(student instanceof Student);//true
System.out.println(student instanceof Teacher);//语法错误
System.out.println(student instanceof String);//语法错误
Object object1=new Person();
System.out.println(object1 instanceof Person);//true
System.out.println(object1 instanceof Object);//true
System.out.println(object1 instanceof Student);//false
System.out.println(object1 instanceof Teacher);//false
System.out.println(object1 instanceof String);//false
}
//若多项引用与特定类存在父子类关系则不会出现语法错误,否则出现语法错误,因为两种类型毫无关系
//若对象是特定类的父类返回false,若是特定类及其子类返回true
类对象的类型转换
类型转换 :父类->子类
向上转型:子类对象转换成父类,会丢失一些方法
向下转型:父类对象转换成子类,要强制转换
作用:可以相互转换类型方便方法使用,减少重复代码
static关键字
//静态导入包:用来导入类中的静态方法或静态变量,导入后可以直接使用方法名而不必ClassNmae.方法
import static java.lang.Math.random
public class person{
{
//匿名代码块,创建对象前即创建,在构造器之前
}
static{
//静态代码块。类加载便执行,只执行一次
}
}
抽象类
通过abstract关键字修饰
//用abestract修饰的类叫抽象类,修饰的方法叫做抽象方法,抽象类中的抽象方法没有方法体,其具体实现由继承该抽象类的子类实现
public abstract class Teacher {
public abstract void doSomethin();
}
特点:
- 抽象类不能实例化,只能靠子类实现它
- 抽象类中可以有非抽象方法
- 有抽象方法的一定是抽象类
抽象类仍然具有一定的局限性即只能单继承,想要实现多继承需要通过接口实现,接口类似于抽象类
接口
通过interface关键字定义
- 普通类:只有具体实现
- 抽象类:具体实现和规范(抽象方法)都有
- 接口:只有规范,自己无法写方法,实现约束和实现分离
接口是规范,定义一组规则。
接口的本质是契约
接口是面向对象的精髓,是对对象的抽象
public interface Interface{
//定义的属性默认为常量 public stativ final(很少使用)
int AGE=99;
//接口中默认所有定义方法为public abstract
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
// 接口都需要有实现类
public class Interfaceimp implements Iterface{
@Overeide
public void add(String name){
};
@Overeide
public void delete(String name){
};
@Overeide
public void update(String name){
};
@Overeide
public void query(String name){
};
}
//接口实现多继承
public class Interfaceimp implements Iterface1,Iterface2{
}
接口特点:
- 定义约束
- 定义一些方法,让不同的人实现
- public abstrac
- public staticfinal
- 接口不能被实例化,没有构造方法
- implements可以实现多个接口
- 实现类必须要重写接口中的方法
内部类
在一个类中定义另一个类
public class Outer{
private int id=10;
public void out(){
System.out.println("外部类方法");
}
class Inter{
public void in(){
System.out.println("内部类方法");
}
//内部类可以获取外部类的私有属性
public void getID(){
System.out.println(id);
}
}
public static void main(String[] args) {
//实例化外部类和内部类
Outer outer = new Outer();
Outer.Inter inter = outer.new Inter();
}
}
----------------------------------------------------------
public class Outer{
private int id=10;
public void out(){
System.out.println("外部类方法");
}
//静态内部类
class Inter{
public void in(){
System.out.println("内部类方法");
}
//静态内部类可以获取外部类的私有属性,因为在编译时就生成
public void getID(){
System.out.println(id);
}
}
public static void main(String[] args) {
//实例化外部类和内部类
Outer outer = new Outer();
Outer.Inter inter = outer.new Inter();
}
}
-------------------------------------------------------------
public class Outer{
}
//在一个类文件下可以有多个class类,但只能定义一个public类
class A{
}
----------------------------------------------------------------
public class Outer{
//局部内部类
public void method(){
class Inner{
}
}
}
-----------------------------------------------------------------
//匿名内部类,没有名字去初始化类,不用把实例保存到变量中
class Apple{
public void eat(){
}
}
public class Test{
public static void main(String[] args) {
new Apple().eat();
}
}
异常机制
软件和层序在运行过程中遇到的异常问题叫做异常
三种异常类型:
- 检查性异常,最具代表行的检查行异常是用户的错误或问题引起的异常,程序员无法预见。例如要打开一个不不存在的文件。这些异常在编译时不能被简单的忽略。
- 运行时异常,运行时异常指可能被程序员忽视的异常。与检查性宜昌襄樊,运行时异常可以在编译时被忽略。
- 错误ERROR:错误不是异常,而实脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译时检查不到
java异常体系结构:
- java把异常当作对象处理,并定义了一个基类java.lang.Throwable作为所有异常的超类。
- 在java API中定义了很多异常类,这些异常类被分为两大类,错误Error和异常Exception
Error
- Error类对象由java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关
- java虚拟机运行错误,当JVM不再有继续执行操作所需的内存资源时,将出现OutOfMemoryError。这些异常发生时,java虚拟机一般会选择线程终止
- 发生在虚拟机试图执行应用时,如类定义错误(NoClassDefFoundError)。链接错误(LinkageError)。这些错误时不可查的因为他们在应用程序的控制和处理能力之外,而且绝大多数时程序运行时不允许出现的状况
Exception
- Exception分支中哟一个重要的子类RuntimeException(运行时异常)
- 这些异常一般是由程序逻辑错误引起的,程序应从逻辑角度尽可能避免这类异常的发生
Error和Exception的区别:Error通常时灾难性的致命的错误,时程序无法控制和处理的,当出现这些错误时,JVM一般会选择终止线程;Excrption通常情况下是可以被程序处理的,而且在程序中应该尽可能地区处理这些异常
异常处理:抛出异常,捕获异常
五个关键字:try,catch,finally,throw,throws
public static void main(String[] args) {
int a=1;
int b=0;
//try跟catch必须成对出现,finally可以不要。可以有多个catch捕获多种异常,但catch捕获的异常需从小到大捕获,否则小地异常会提前被捕获出错
try {
System.out.println(a / b);
}catch (ArithmeticException e){
e.printStackTrace();//打印系统错栈信息
}finally {
System.out.println("finally");
}
}
//主动抛出异常throw,throws
//假设在方法中处理不了这个异常,在方法上抛出异常throws
public void test(int a.int b) throws ArithmeticException{
if(b==0){
throw new ArithmeticException();//主动抛出异常
}
}
Idea快捷键:
生成语句包裹块,ctrl+alt+T,注意登录qq可能快捷键被qq占用导致失效,此时可退出qq或ctrl+win+alt+T
idea中错误处理提示 alt+Enter
自定义异常
除使用java内置地遗产给外,用户可自定义异常。用户自定义异常类只需继承Exception类即可
自定义异常类的几个步骤:
- 创建自定义异常类
- 在方法中通过throw关键字抛出异常对象
- 如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws指明要抛出给方法调用者的异常,继续执行下一步操作。
- 在出现异常方法的调用者中捕获并处理异常
异常处理中的经验总结:
- 处理运行时异常时,采用逻辑区合理规避同时辅助try-catch处理
- 在多重catch块后谜案,可以加一个catch(Exception)来处理可能被遗漏的异常
- 对于不确定的代码,也可以加上try-catch,处理潜在的异常
- 尽量去处理异常,切记知识简单的调用printStackTrace()去打印输出
- 具体如何处理异常,要根据不同的业务需求和异常类型决定
- 尽量添加finally语句块去释放占用的资源