java环境的配置
1、添加环境变量 JAVA_HOME 选择jdk路径
2、添加两个path路径
1、%JAVA_HOME%\bin
2、%JAVA_HOME%\jre\bin
3、 命令行输入 java -version 确认环境配置成功
0、IDEA的使用
- 新建一个空项目
-
选择空项目
-
为项目命名,并确认
-
新建一个Module
-
选择Java,JDK1.8,命名
-
设置项目结构(Project Structure)
1、Java注释
###1、单行注释
//Hello World
2、多行注释
/*
Hello World
*/
3、文档注释
2、数据类型
java是强类型语言
1、基本数据类型
2、引用类型
类、接口类型、数组类型、枚举类型、注解类型。
3、二者的区别
基本数据类型在被创建的时,会在栈上划分一块内存空间,并将数值直接存储在栈上。(不用new空间)
public class Demo01 {
public static void main(String[] args) {
// 整数拓展: 进制 二进制0b 十进制 八进制0 十六进制0x
int i = 10;
int i2 = 010; // 八进制0
int i3 = 0x10; // 十六进制0x 0~9 A~F 15
System.out.println(i);
System.out.println(i2);
System.out.println(i3);
System.out.println(" ==========================");
// ================================
// 浮点数拓展? 银行业务怎么表示?钱
// BigDecimal 数学工具类
// ================================
// float 有限 离散 舍入误差 大约
// double
// 最好完全避免使用浮点数进行比较
// 最好完全避免使用浮点数进行比较
// 最好完全避免使用浮点数进行比较
float f = 0.1f; // 0.1
double d = 1.0/10; // 0.1
System.out.println(f==d); // false
float d1 = 23131313131313131f;
float d2 = d1 + 1;
System.out.println(d1==d2); // true
}
}
3、类型转换
注意点:
1. 不能对布尔值进行转换
2. 不能把对象类型转换为不相干的类型
3. 在把高容量转换到低容量的时候,需要强制转换,反之则不用
4. 转换的时候可能存在内存溢出,或者精度问题!
int i = 128;
byte b = (byte)i; // 内存溢出
// 强制转换 (类型)变量名 高-->低
// 自动转换 低-->高
System.out.println(i);
System.out.println(b);
/*
注意点:
1. 不能对布尔值进行转换
2. 不能把对象类型转换为不相干的类型
3. 在把高容量转换到低容量的时候,需要强制转换,反之则不用
4. 转换的时候可能存在内存一处,或者精度问题!
*/
System.out.println("==================");
System.out.println((int)23.7); // 23
System.out.println((int)-45.89f); // -45
System.out.println("===================");
char c = 'a';
int d = c + 1;
System.out.println(d);
System.out.println((char)d);
操作比较大的数的时候,注意溢出问题
JDK7 新特性,数字之间可以用下划线分割
int money = 10_0000_0000;
int years = 20;
int total = money*years; //-1474836480,计算的时候溢出了
long total2 = money*years; //默认是int,转换之前已经存在问题了
long total3 = money*(long)years; //先把一个数转换为long
System.out.println(total3);
// L l 用L不用l
4、变量
变量是什么:就是可以变化的量!
Java是一种强类型语言,每个变量都必须声明其类型。
Java变量是程序中最基本的存储单元,其要素包括变量名,变量名类型和作用域。
type varName [=value] [{,varName[=value]}];、
//数据类型 变量名 = 值;可以使用逗号隔开来声明多个同类型变量。
注意事项:
1. 每个变量都有类型,类型可以是基本类型,也可以是引用类型。
2. 变量名必须是合法的标识符。
3. 变量声明是一条完整的语句,因此每一个声明都必须以分号结束
变量作用域
- 类变量
- 实例变量
- 局部变量
public class Variable{
static int allClicks = 0; // 类变量
String str="hello world"; // 实例变量
public void method(){
int i = 0; // 局部变量
}
}
Java访问修饰符
修饰符,不存在先后顺序
final
对类:该类不可被继承。
- 在使用final修饰类的时候,要注意谨慎选择,除非这个类真的在以后不会用来继承或者出于安全的考虑,尽量不要将类设计为final类。
对方法:锁定方法,防止任何继承类修改它的含义。
- 只有在想明确禁止 该方法在子类中被覆盖的情况下才将方法设置为final的。
对变量:基本数据类型一旦初始化后,便不能更改;引用对象初始化后,便不能再指向新的对象。
public class Demo04 {
// 修饰符,不存在先后顺序
static final double PI = 3.14;
public static void main(String[] args) {
System.out.println(PI);
}
}
变量的命名规范
-
所有变量、方法、类名:见名知意
-
类成员变量:首字母小写和驼峰原则:monthSalary 除了第一个单词以外,后面的单词首字母大写
lastname lastName
-
局部变量:首字母小写和驼峰原则
-
常量:大写字母和下划线: MAX_VALUE
-
类名:首字母大写和驼峰原则:Man,GoodMan
-
方法名:首字母小写和驼峰原则:run(),runRun()
5、运算符
-
算术运算符:+,-,*,/,%,++,–
-
赋值运算符:=
-
关系运算符:>,<,>=,<=,==,!= instanceof
instanceof:二元操作运算符,左边的对象是否是它右边的类的实例,返回 boolean 的数据类型。
-
逻辑运算符:&&,||,!
-
位运算符:&,|,^,~,>>,<<,>>> (了解)
-
条件运算符:?
-
扩展复制运算符:+=,-=,*=,/=
位运算符
/*
A = 0011 1100
B = 0000 1101
---------------------
A&B = 0000 1100
A|B = 0011 1101
A^B = 0011 0001
~B = 1111 0010
左移 右移 效率极高
<< 左移 *2
>> 右移 /2
*/
字符串连接符
int a = 10;
int b = 20;
// 字符串连接符 + , String
System.out.println(""+a+b); // 输出 1020
System.out.println(a+b+""); // 输出 30
三元运算符
// x ? y : z
// 如果x==true,则结果为y,否则结果为z
int score = 50;
String type = score < 60 ? "不及格":"及格"; //必须掌握
// if
System.out.println(type);
6、包机制
打包语句:
package com.Ming.lesson01;
导包语句:
import com.Ming.lesson01.Demo01;
import com.Ming.lesson01.*; //包含lesson01下的所有的类
相当于文件夹
一般利用公司域名导致作为包名
开发规范相关书籍:《阿里巴巴开发手册》
7、Scanner
通过Scanner类来获取用户的输入
基本语法:
Scanner s = new Scanner(System.in);
通过Scanner类的next()
与nextLine()
方法获取输入的字符串,在读取前我们一般需要使用hasNext()
与hasNextLine()
判断是否还有输入的数据。
注意:凡是io流的类,如果不关闭,就会一直占用资源,所以用完记得使用 s.close() 来关闭scanner
- next()
- 1、一定要读取到有效字符后才可以结束输入
- 2、对输入有效字符之前遇到的空白,next()方法会自动将其去掉
- 3、只有输入有效字符后才将其后面的空白作为分隔符或结束符
- 4、next()不能得到带有空格的字符串
- nextLine()
- 1、以Enter为结束符。也即是说nextLine()方法返回的是输入回车之前的所有字符。
- 2、可以获得空白。
8、命令行传参
public class args {
public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
System.out.println("args["+i + "] :" + args[i]);
}
}
}
生成 args.class 文件
javac args.java
退回到src文件夹
java com.Ming.method.args Hello I'm Spiderman
输出结果
9、可变参数
public static void printMax(double... numbers){
//如果参数为空,则退出函数
if(numbers.length == 0){
System.out.println("No argument passed");
return;
}
double result = numbers[0];
//排序
for (double number : numbers) {
if (number > result){
result = number;
}
}
System.out.println("最大值为:" + result);
}
10、数组
静态初始化:创建 + 赋值
int[] a = {1,2,3,4,5};
System.out.println(a[0]);
动态初始化:包含默认初始化
int[] b = new int[10];
b[0] = 10;
b[1] = 10;
1.稀疏数组
实现源码
public class ArrayDemo01 {
public static void main(String[] args) {
//疏数组
//1.创建一个二维数组11*11 0:没有妻子,1:黑棋 2:白起
int[][] array1 = new int[11][11];
array1[1][2] = 1;
array1[2][3] = 2;
//输出原始的数组
System.out.println("输出原始的数组");
for (int[] ints : array1) {
for (int anInt : ints) {
System.out.print(anInt + " ");
}
System.out.println();
}
System.out.println("======================");
System.out.println("转换为稀疏数组");
// 2.转换为稀疏数组保存
// 获取有效值的个数
int sum = 0;
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if(array1[i][j] != 0){
sum++;
}
}
}
System.out.println("有效值的个数:" + sum);
int[][] array2 = new int[sum+1][3];
array2[0][0] = 11;
array2[0][1] = 11;
array2[0][2] = sum;
// 遍历二维数组,将非零的值,存放到稀疏数组中
int count = 0;
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1[i].length; j++) {
if(array1[i][j] != 0){
count++;
array2[count][0] = i;
array2[count][1] = j;
array2[count][2] = array1[i][j];
}
}
}
// 输出稀疏数组
System.out.println("输出稀疏数组");
for (int i = 0; i < array2.length; i++) {
for (int j = 0; j < array2[i].length; j++) {
System.out.print(array2[i][j]+"\t");
}
System.out.println();
}
// 还原
System.out.println("===========================");
System.out.println("还原");
// 1.读取稀疏数组
int[][] array3 = new int[array2[0][0]][array2[0][1]];
// 2.给其中的元素还原它的值
for (int i = 1; i < array2.length; i++) {
array3[array2[i][0]][array2[i][1]] = array2[i][2];
}
// 3.打印
for (int[] ints : array3) {
for (int anInt : ints) {
System.out.print(anInt + " ");
}
System.out.println();
}
}
}
11、方法
1、静态方法(static)
和类一起加载
public class Demo02{
public static void main(String[] args){
// 和类一起加载的
public static void a(){
// 会调用失败,因为调用了一个不存在的方法
b();
}
// 类实例化 之后才存在
public void b(){
}
}
}
12、面向对象
1、类与对象
类是一个模板:抽象,对象是一个具体的实例
2、方法
定义、调用!
3、对应的引用
引用类型:除了8大基本类型
对象是通过引用来操作的:栈 --> 堆
4、属性:字段Field 成员变量
默认初始化:
数字:0 0.0
char: u0000
boolean: false
引用:null
修饰符 属性类型 属性名 = 属性值
5、对象的创建和使用
- 必须使用new 关键字创建对象,构造器 Person kuangshen = new Person();
- 对象的属性 kuangshen.name
- 对象的方法 kuangshen.sleep()
6、类:
静态的属性 属性
动态的行为 方法
1、封装
2、继承
IDEA快速写出set和get的快捷键:alt+insert
super注意点:
1、super调用父类的构造方法,必须在构造方法的第一个
2、super必须只能出现在子类的方法或者构造方法中!
3、super和this不能同时调用构造方法!
Vs this:
- 代表的对象不同
- this:本身调用者这个对象
- super:代表父类对象的应用
- 前提
- this:没有继承也可以使用
- super:之恶能在继承条件下才可以使用
- 构造方法
- this():奔雷的构造
- super():父类的构造
1、重写
需要有继承关系,子类重写父类的方法!
1、方法名必须相同
2、参数列表必须相同
3、修饰符:范围可以扩大但不能缩小:public>protected>default>private
4、抛出的异常:范围可以被缩小,但不能扩大:ClassNotFoundException<-Exception(大)
重写,子类的方法和弗雷必须要一直;方法体不同!
有些方法不能被重写
1、static 方法,属于类,它不属于实例
2、final 常量
3、private 方法
3、多态
对象能执行哪些方法,主要看对象左边的类型,和右边关系不大!
父类型,可以指向子类,但是不能调用子类独有的方法
package com.Ming.inherit.demo03;
public class Application {
public static void main(String[] args) {
//一个对象的实际类型是确定的
//new Student();
//new Person();
//可以指向的引用类型就不确定了:父类的引用指向子类
Student s1 = new Student();
//Person 父类型,可以指向子类,但是不能调用子类独有的方法
Person s2 = new Student();
Object s3 = new Student();
//对象能执行哪些方法,主要看对象左边的类型,和右边关系不大!
((Student)s2).eat();
s2.run();
}
}
多态注意事项:
1、多态是方法的多态,属性没有多态
2、父类和子类,有联系 否则会出现 类型转换异常! ClassCastException!
3、存在条件:继承关系,方法需要重写,父类引用指向子类对象! Father f1 = new Son();
1、instanceof的使用
注意:
Object object = new Student();
引用类型为Object,实际类型为Student
X instanceof Y
- 能不能编译通过 取决于X的引用类型与Y是否有父子关系
- 是否为true 取决于X的实际类型是否是Y的子类
// Object > Person > Student
// Object > Person > Teacher
Object object = new Student();
//System.out.println(X instanceof Y);
// 能不能编译通过 取决于X的引用类型与Y是否有父子关系
// 是否为true 取决于X的实际类型是否是Y的子类
System.out.println(object instanceof Student); //true
System.out.println(object instanceof Person); //true
System.out.println(object instanceof Object); //true
System.out.println(object instanceof Teacher); //true
System.out.println(object instanceof String); //false
System.out.println("==================================");
Person person = new Student();
System.out.println(person instanceof Student); //true
System.out.println(person instanceof Person); //true
System.out.println(person instanceof Object); //true
System.out.println(person instanceof Teacher); //true
//System.out.println(person instanceof String); //编译报错!
System.out.println("==================================");
Student person = new Student();
System.out.println(student instanceof Student); //true
System.out.println(student instanceof Person); //true
System.out.println(student instanceof Object); //true
//System.out.println(student instanceof Teacher); //编译报错!
//System.out.println(person instanceof String); //编译报错!
1、父类引用指向子类的对象
2、把子类转换为父类,向上转型;
3、把父类转换为子类,向下转型;强制类型转换
4、方便方法的调用,减少重复的代码!
2、static的使用
1、静态导入包
//静态导入包
import static java.lang.Math.random;
import static java.lang.Math.PI;
public class test {
public static void main(String[] args) {
System.out.println(random());
System.out.println(PI);
}
}
2、静态变量
3、静态方法
静态方法不能使用非静态方法,因为静态方法和类一同加载,而此时非静态方法还未加载。
4、静态代码块
一个类的静态代码块,只在第一次实例化时执行。
代码块执行顺序:静态代码块(只执行一次)>匿名代码块>构造代码块
3、其他
1、抽象类
abstract 抽象类:类 extends:单继承~ (接口可以多继承)
abstract,抽象方法,只有方法名字,没有方法的实现!
1、不能new这个抽象类,只能靠子类区实现它:约束!
2、抽象类种可以写普通的方法
3、抽象方法必须在抽象类中
抽象的抽象:约束
2、接口
implements
作用:
- 约束
- 定义一些方法,让不同的人实现
- public abstract
- public static final
- 接口不能被实例化,接口中没有构造方法
- implements可以实现多个接口
- 必须要重写接口中的方法
UserService.java
//interface 定义的关键字,接口都需要有实现类
public interface UserService {
//接口中的所有定义起始都是抽象的 public abstract
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
TimeService.java
public interface TimeService {
void timer();
}
UserServiceImpl.java
import java.sql.Time;
// 抽象类:extends~
// 类 可以实现接口 implements 接口
// 实现了接口的类,就必须重写接口中的方法
public class UserServiceImpl implements UserService, TimeService {
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
@Override
public void timer() {
}
}
3、内部类
- 成员内部类
- 静态内部类
- 局部内部类
- 匿名内部类
13、异常处理
java把异常当作对象来处理,并定义了一个基类java.lang.Throwable作为所有异常的父类。
异常体系结构
异常的分类:
- 检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的,例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
- 运行时异常:运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
- 错误ERROR:错误不是异常,而是脱离程序员控制地问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到地。
经验总结:
- 处理运行时异常时,采用逻辑去合理规避同时辅助try-catch处理
- 在多重catch快后面,可以加一个catch(Exception)来处理肯恩会被遗漏的异常
- 对于不确定的代码,也可以加上try-catch,处理潜在的异常
- 尽量去处理异常,切记只是简单地调用printStackTrace()去打印输出
- 具体如何处理异常,要根据不同的业务需求和异常类型去决定
- 尽量添加finally语句块去释放占用的资源