学习资源来自B站狂神说:https://space.bilibili.com/95256449/channel/seriesdetail?sid=393820
Java基本概念
Java特性和优势
- 简单性
- 面向对象 重点在对象和对象之间的接口上
- 可以移植性 write once,run anywhere
- 高性能
- 分布式 通过Url访问资源
- 动态性 反射机制
- 多线程 同时看视频听音乐…等等
- 安全性 异常机制等等
- 健壮性
Java三大版本
-
Write Once,Run Anywher(JVM:java虚拟机,可以跑在所有的平台上,所以可以实现跨平台)
-
JavaSE:标准版(桌面程序,控制台开发…)
-
JavaME:嵌入式开发(手机,小家电…)
-
JavaEE:企业级开发(web端,服务器开发…)
JDK、JRE、JVM
- JDK:Java Development Kit
- JRE:Java Runtime Environment (Java运行时候的环境)
- JVM:Java Virtual Machine (Java虚拟机)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5MSqasmg-1638602264272)(C:/Users/DELL/Desktop/项目/md图片/1612233181684.png)]
Java开发环境
卸载JDK
- 删除java的安装目录
- 删除JAVA_HOME
- 删除path下关于Java的目录
- java-version
安装JDK
-
百度JDK8,找到下载地址
-
同意协议
-
下载电脑对应的版本
-
双击安装JDK
-
记住安装路径 (本机是E://jdk)
-
配置环境变量
- 我的电脑 -》右键 -》属性
- 高级系统设置 -》环境变量
- 配置path变量
-
测试JDK是否安装成功
- 打开cmd
- java -version
Hello world
-
随便新建一个文件夹,存放代码
-
新建一个Java文件
- 文件后缀名为.java
- Hello.java
- 【注意点】系统可能没有显示文件后缀名,我们需要手动打开
-
编写代码 (练习的时候文件路径是 D:\桌面\Daily\学习文档\java语言学习\code)
public class Hello{ public static void main(String[] args){ System.out.print("Hello,World!"); } }
-
编译javac java文件
-
运行class文件,java class文件
可能会遇到的情况
1. 每个单词的大小写不能出现问题,Java是大小写敏感的。
2. 尽量使用英文。有些控制台不支持中文。
3. 文件名和类名必须保持一致。
4. 符号使用了中文。
Java程序运行机制
- 编译型,类似于把一本中文书直接翻译成英文版出售
- 解释型,类似于请了一个翻译来翻译,一句一句解释。对速度要求不高
- 程序运行机制
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ALtqiHQL-1638602264274)(C:/Users/DELL/Desktop/项目/md图片/1612238109188.png)]
java既有编译也有解释,先编译了,到操作系统了再解释。
Java基本语法
注释
-
单行注释
//输出一个Hello world!
-
多行注释
/* 输出一个Hello world! */
-
文档注释 JavaDoc,有一些特定作用
/** * @Description Helloworld */
标识符
关键字
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1QSqT2Dr-1638602264275)(C:/Users/DELL/Desktop/项目/md图片/1612251107492.png)]
Java所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。
数据类型
-
强类型语言,要求变量的使用要严格符合规定,所有变量都必须先定义后使用
-
弱类型语言
Java的数据类型分为两大类
- 基本类型
- 引用类型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KP8Zb8de-1638602264276)(C:/Users/DELL/Desktop/项目/md图片/1612251689866.png)]
这里注意,Long类型要在数据后面加一个L,float类型要在后面j加个F。
//整数拓展: 进制 二进制0b 十进制 八进制0 十六进制0x
int i1 = 10; //10
int i2 = 010; //8
int i3 = 0x10; //16
//===============================================
//浮点数拓展。 银行业务怎么表示?钱
//BigDecimal 数学工具类。不能有误差就用这个使用这个类
//===============================================
//float 有限 离散 舍入误差 大约 接近但不等于
//double
float f = 0.1f; //0.1
float d = 1.0/10; //0.1
System.out.println(f==d); //false
float d1 = 231213213213213f;
float d2 = d1+1;
System.out.println(d1==d2); //true
//===============================================
//字符拓展。
//===============================================
char c1 = 'A';
char c2 = '中';
System.out.println(c1); //A
System.out.println((int)c1); //65
System.out.println(c2); //中
System.out.println((int)c2); //20013
//所有的字符本质还是数字
//编码 Unicode表,2字节 0-65536
char c3 = '\u0061';
System.out.println(c3); //a
//转义字符 \t制表符,\n换行符 等等
类型转换
由于Java是强类型语言,所以要进行有些运算的时候,需要用到类型转换。
-
强制转换 高到低
-
自动转换 低到高
运算中,不同类型的数据先转化为同一类型,然后进行运算。
int i = 128;
byte b = (byte)i; //内存溢出,byte的范围是 -128 - 127
//强制转换 (类型)变量名 高->低
//自动转换 低->高
System.out.println(i); //128
System.out.println(b); //-128
-
注意点
-
不能对布尔值进行转换
-
不能把对象类型转换为不相干的类型
-
在把高容量转换到低容量的时候,强制转换
-
转换的时候可能存在内存溢出,或者精度问题!
-
变量
注意事项:
- 每个变量都有类型,类型可以是基本类型,也可以是引用类型。
- 变量名必须是合法的标识符。
- 变量声明是一条完整的语句,因此每一个声明都必须以分号结束。
变量作用域:
- 类变量,要加一个static关键字。从属于本类。
- 实例变量,从属于对象。如不不自行初始化,值会变成这个类型的默认值。除了基本类型,其余的默认值都是null。
- 局部变量,必须声明和初始化值。
public class Variable{
static int allClicks = 0; //类变量
String str = "hello world!"; //实例变量
public void method(){
int i = 0; //局部变量
}
}
常量
//final 常量名 = 值;
final double PI = 3.14;
常量名一般使用大写!
变量的命名规范
- 类成员变量:首字母小写和驼峰原则:monthSalary
- 常量:大写字母和下划线:MAX_VALUE
- 类名:首字母大写和驼峰原则:Man,GoodMan
- 方法名:首字母小写和驼峰原则:run(),runRun()
包机制
为了更好地组织类,Java提供了包机制,用于区别类名的命名空间。
包语句的语法格式为
package pkg1[. pkg2[. pkg3...]];
**一般利用公司域名倒置作为包名。**www.baidu.com -> com.baidu.www
为了能够使用某一个包的成员,我们需要在Java程序中明确导入该包。使用“import”语句可完成此功能
import package1[.package2.(classname|*)]; //*代表通配符,表示把对应包下的所有东西都导入进来
JavaDoc
javadoc命令是用来生成自己的API文档的
- 参数信息
- @author 作者名
- @version 版本号
- @since 指明需要最早使用的jdk版本
- @param 参数名
- @return 返回值情况
- @throws 异常抛出情况
//javadoc格式
/**
*@author Ausen
*@version 1.0
*/
在cmd中打开javadoc文件对应路径,输入命令
javadoc -encoding UTF-8 -charset UTF-8 Doc.java
会生成一堆html,既是把java文件编译成文档,方便阅读。
Scanner对象
Scanner类来获取用户的输入
Scanner s = new Scanner(System.in);
通过Scanner类的next()与nextline()方法获取输入的字符串,在读取前我们一般需要使用hasNext()与hasnextLine()判断是否还有输入的数据。
/* next方式接收输入 */
public class demo1 {
public static void main(String[] args) {
//创建一个扫描器对象,用于接收键盘数据
Scanner scanner = new Scanner(System.in);
System.out.println("使用next方式接收:");
//判断用户有没有输入字符串
if(scanner.hasNext()){
//使用next方式接收
String str = scanner.next();
System.out.println("输出的内容为"+str);
}
//凡是属于IO流的类如果不关闭会一直占用资源,要养成良好的习惯用完就关掉
scanner.close();
}
}
/* nextLine方式接收输入 */
public class demo1 {
public static void main(String[] args) {
//创建一个扫描器对象,用于接收键盘数据
Scanner scanner = new Scanner(System.in);
System.out.println("使用next方式接收:");
//判断用户有没有输入字符串
if(scanner.hasNextLine()){
//使用next方式接收
String str = scanner.nextLine();
System.out.println("输出的内容为"+str);
}
//凡是属于IO流的类如果不关闭会一直占用资源,要养成良好的习惯用完就关掉
scanner.close();
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yUpS4S4G-1638602264278)(C:/Users/DELL/Desktop/项目/md图片/1612337460092.png)]
**next()**遇到空格就断了,**nextLine()**遇到回车断。
函数中的可变参数
—不定向参数
- 在方法声明中,在指定参数类型后加一个省略号 …
- 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
public static void Demo(double... numbers){
//number为一个数组对象,其中有length属性,可访问其长度,根据调用函数的情况决定
}
数组声明创建
//声明数据变量
dataType[] arrayRefVar; //首选的方法
或
dataType arryRefVar[]; //效果相同,但不是首选的方法
//创建数组
dataType[] arrayRefVar = new dataType[arraySize];
//静态初始化
int[] a = {0,1,2,3,4,5};
数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。
数组的循环
for(int array: a){
//遍历数组中的每一个值
System.out.print(array);
}
多维数组
int[][] a = new int[2][5];
Arrays类
包含操作数组方法的工具,包括排序、查找、复制等等。
import java.util.Arrays
面向对象编程
方法的调用
静态方法:
//在另外一个类中定义方法,用static定义
//Student.java
public class Student{
public static void say(){
System.out.print("学生说话了");
}
}
//Demo.java
public class Demo{
public static void main(String[] args){
//可以直接调用
Student.say();
}
}
非静态方法:
//在另外一个类中定义方法,不用static定义
//Student.java
public class Student{
public void say(){
System.out.print("学生说话了");
}
}
//Demo.java
public class Demo{
public static void main(String[] args){
//需要创建对象之后调用方法
Student student = new Student();
student.say();
}
public static void a(){
//!无法直接调用b(),因为static是和类一起加载的,而b()是类实例化的时候才加载
b();
}
public void b(){
}
}
构造器
就是c++中的构造函数,用于类初始化其实例变量的值。
public class Student{
String name;
//构造器,必须和类的名字相同
//无参构造
public Student(){
this.name = "Jijie";
}
//有参构造,一旦定义了有参构造,无参构造必须显式定义!!!
//无参构造可以 public Student(){} 就可
public Student(String name){
this.name = name;
}
}
在IDE中可以通过 alt+insert 组合键方便定义构造函数。
在构造器执行顺序中,父类的构造器先执行,然后执行子类的构造器。
调用父类的构造器,必须要在子类构造器的第一行。
封装的一些概念
实现高内聚低耦合,类中属性一般private,用类中的方法来访问和操作它。
- 提高程序的安全性,保护数据
- 隐藏代码的实现细节
- 统一接口
- 系统可维护性增加了
继承的一些概念
Java中类只有单继承,没有多继承
public class Person{}
public class Student extends Person{}
public class Teacher extends Person{}
私有private的不继承。
Java中所有的类,都默认直接或间接继承Object类。
若类定义时用final定义了,则不能够继承了。
super
与this对比。super是父类的属性,this是本类属性。
方法重写
需要有继承关系,子类重写父类的方法。
重写都是方法的重写,和属性无关。
- 方法名必须相同
- 参数列表必须相同
- 修饰符:范围可以扩大 ;public > protected > default > private
- 抛出的异常:范围可以被缩小,但不能扩大;ClassNotFoundException() -> Exception(大)
A a = new A();
a.test();
//父类的引用指向了子类
B b = new A(); //子类重写了父类的方法,所以调用子类的方法
b.test();
- 静态的方法和非静态的方法区别很大!
- 静态方法:方法的调用只和左边,定义的数据类型有关。
- 非静态:重写。
为什么需要重写:父类的功能,子类不一定需要,或者不一定满足。
对象能够执行哪些方法,主要看对象左边的类型,和右边的类型关系不大。
多态
// Student能调用的方法都是自己的或者继承父类的
Student s1 = new Student();
// Person父类型,可以指向子类,但是不能调用子类特有的方法
Person s2 = new Student();
Object s3 = new Student();
-
多态是方法的多态,属性没有多态
-
父类和子类,有联系,类型转换异常!ClassCastException!
-
存在条件:继承关系,方法需要重写,父类引用指向子类对象! Father f1 = new Son();
- static方法,属于类,它不属于实例
- final 常量
- private 方法
-
父类引用指向子类的对象
-
把子类转换为父类,向上转型
-
把父类转换为子类,向下转型;强制转换
-
方便方法的调用,减少重复的代码!
instanceof
instanceof(类型转换)引用类型,判断一个对象是什么类型~
//Object > String
//Object > Person > Teacher
//Object > Person > Student
Object object = new Student();
System.out.print(object instanceof Student); //True
System.out.print(object instanceof Person); //True
System.out.print(object instanceof Object); //True
System.out.print(object instanceof Teacher); //False
System.out.print(object instanceof String); //False
//-----------------------------------------------------------
Person person = new Student();
System.out.print(person instanceof Student); //True
System.out.print(person instanceof Person); //True
System.out.print(person instanceof Object); //True
System.out.print(person instanceof Teacher); //False
//System.out.print(person instanceof String); //编译报错
//-----------------------------------------------------------
Student student = new Student();
System.out.print(student instanceof Student); //True
System.out.print(student instanceof Person); //True
System.out.print(student instanceof Object); //True
//System.out.print(student instanceof Teacher); //编译报错
//System.out.print(student instanceof String); //编译报错
System.out.print(X instanceof Y); //能不能编译通过,取决于X和Y是否存在父子关系
static详解
static属性的变量在所有相同的类中内存共享。
public class Person{
//2:赋初始值
{
System.out.println("匿名代码块");
}
//1:只执行一次
static{
System.out.println("静态代码块");
}
//3
public Person{
System.out.println("构造器");
}
public static void main(String[] args){
Person person1 = new Person();
System.out.println("==========");
Person person2= new Person();
}
}
/*
静态代码块
匿名代码块
构造器
==========
匿名代码块
构造器
*/
执行顺序:
静态代码块 - 匿名代码块 - 构造器
静态代码块只执行一次。
静态导入包
import static java.lang.Math.random
public class Test{
public static void main(String[] args){
//这里如果没有用上面的static导入包,则需要写Math.random()
System.out.println(random());
}
}
抽象类
abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类。
一旦类里面有抽象方法,那么这个类一定得声明为抽象类。
抽象出来,提高开发的效率。
//Action.java
//abstract 抽象类:类 extends: 单继承 (接口可以多继承)
public abstract class Action{
//约束,有人来帮我们实现
//abstract,抽象方法,只有方法名字,没有方法的实现!
public abstract void doSomething();
/*
1. 不能new这个抽象类,只能靠子类去实现它:约束!
2. 抽象类可以写普通的方法。
3. 抽象方法必须在抽象类中。
*/
}
//A.java
public class A extends Action{
}
接口
就是规范!自己无法写方法,专业的约束,约束和实现分离:面向接口编程。
声明类的关键字是class,声明接口的关键字是interface
//UserService.java
//interface定义的关键字,接口都需要有实现类
//抽象思想~架构师
public interface UserService{
//常量~public static final常量
int AGE = 99;
//接口中的所有定义其实都是抽象的 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
//类可以实现接口 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(){
}
}
作用:
- 约束
- 定义一些方法,让不同的人实现。
- public abstract类。
- public static final属性。
- 接口不能被实例化~接口中没有构造方法。
- implements可以实现多个接口。
- 必须要重写接口中的所有方法。
内部类
内部类就是在类的内部再定义一个类。
//Outer.java
public class Outer{
private int id;
public void out(){
System.out.println("这是外部类的方法");
}
public class inner1{
public void in(){
System.out.println("这是内部类的方法");
}
//可以获得外部类的私有属性
public void getID(){
System.out.println(id);
}
public void method(){
//局部内部类
class Inner2{
public void in(){
}
}
}
}
//一个java文件可以有多个class类,但只能有一个public class
class A{
public static void main(String[] args){
}
}
//Application.java
public class Application{
public static void main(String[] args){
Outer outer = new Outer();
//通过这个外部类来实例化内部类
Outer.Inner inner = outer.new Inner1();
inner.in();
}
}
异常机制
在Java中,异常就是对象
异常处理的五个关键字:try、catch、finally、throw、throws
int a = 1;
int b = 0;
try{
System.out.println(a/b);
}catch(ArithmeticException e){ //catch里面的参数是想要捕获的异常类型
//catch捕获异常,可以写多个catch,最大的异常写在最后面,层层递进,因为大的在上面小异常会被覆盖
System.out.println("程序出现异常,变量b不能为0");
}catch(){
}finally{
//finally区可以不要
//处理善后工作,怎样都会运行这部分代码块。 关闭IO,资源,关闭等。
System.out.println("finally");
}
主动抛出异常
//主动抛出异常,一般在方法中使用
public static void main(String[] args){
try{
new Test().test(1,0);
}catch(ArithmeticException e){
e.printStackTrace();
}
}
//假设这方法中,处理不了这个异常。方法上抛出异常
public void test(int a, int b)throws ArithmeticException{
if(b==0){
throw new ArithmeticException();
}
}
自定义异常
使用Java内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户还可以自定义异常。用户自定义异常类,只需继承Exception类即可。
在程序中使用自定义异常类,大体可分为以下几个步骤:
- 创建自定义异常类
- 在方法中通过throw关键字抛出异常对象。
- 如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作。
- 在出现异常方法的调用者中捕获并处理异常。
//MyException.java
//继承Exception超类
public class MyException extends Exception{
//传递数字>10
private int detail;
//构造器
public MyException(int a){
this.detail = a;
}
//toString 异常的打印信息
@Override
public String toString(){
return "MyException{"+detail+"}";
}
}
//Test.java
public class Test{
//在类中用关键字throws接收异常
static void test(int a)throws MyException{
System.out.println("传递的参数为"+a);
if(a>10){
throw new MyException(a); //函数中用throw抛出异常
}
System.out.println("ok");
}
public static void main(String[] args){
test(11);
}
}