Java学习笔记

基础语法

IDEA快捷操作

Ctrl + D : 复制当前行到下一行

psvm : public static void main

sout : System.out.println();

for循环: fori Enter

Alt + Insert :

  • 插入构造器
  • 插入get、set方法
  • @override 重写方法

Ctrl + H :继承树

Ctrl + Alt + T:自动生成异常等

Alt + Enter:提示如何处理异常

数据类型

基本数据类型

  • 整型 默认值 0

    int 4字节

    byte 1字节

    short 2字节

    long 8字节,定义时要在后面加L,大小写均可,但是为了便于阅读用L

  • 浮点型 默认值0.0

    double 8字节,浮点数默认类型,如果要使用float类型要在后面加F

    float 4字节,定义时要在后面加F

  • 字符型

    char 2字节

    注:String是一个类,不是基本数据类型,也不是关键字

  • 布尔类型 默认值为false

    boolean 1位

引用数据类型

  • 接口
  • 数组

默认值为null

数据类型拓展

  • 进制表示

    ​ 二进制:0b110 = 6

    ​ 八进制:0110 = 72

    ​ 十六进制:0x110 = 272

    浮点数会有舍入误差,最好完全避免使用浮点数直接比较!

  • 字符的本质也是数字

ASCII编码:‘A’~‘Z’ 65~90 ‘a’~‘z’ 97~122

Unicode编码:2字节 0~65535

  • 强制类型转换

    高>>低 可以强转 (类型)变量名

    低>>高 自动转换

    byte short int long float double

    布尔值不可以类型转换

    可能会有溢出或者精度的问题

    不能把对象类型转换成不相干的类型

	char c = 'A'
 	System.out.println((int)c);  //强制转换  把int括起来
  • 转义字符

    /t 制表符 /n 换行

常量与变量

常量

常量(Constant) 初始化(initialize)之后不会再改变

final Max = 65535; //final 常量名 = 值 ; 常量名一般大写开头

变量

变量的作用域
  • 局部变量: 作用在方法里,必须声明和初始化值
  • 实例变量:方法外面,类的里面,从属于对象,要先创建对象才可以使用,可以不进行初始化
  • 类变量:加一个static关键字,会从属于类,跟实例变量一样,写在方法外面,类的里面,可以直接调用,不需要创建对象
变量命名规范
1.见名知意
2.类成员变量:首字母小写与驼峰原则:mouthSalary,除第一个字母,其余用大写开头
3.局部变量:首字母小写与驼峰原则
4.常量:全部大写,可加下划线  MAX_VALUE
5.类名:首字母大写与驼峰原则:ManGoodMan
6.方法名:首字母小写与驼峰原则,run(),runRun()

操作符

关系运算符

大于 > 小于 < 等于 = 运算返回的是Boolean类型 true/ false

  • a++与++a
int a = 3;
int a1 = 3;
int b = a++;  //先把a赋值给b,然后a自增    执行完这行代码后,b=3,a=4
int b1 = ++a1; //a1先自增,然后才赋值给b   执行完这行代码后,b1=4,a1=4

逻辑运算符

与(AND)&& 或(OR)|| 非(NOT)!

短路运算

boolean a = true;
boolean b = false;

System.out.println("a&&b:"+(b&&a));  //b为假,后面的不会执行,直接输出假
System.out.println("a||b:"+(a||b));  //a为真,后面的不会执行,直接输出真

字符串连接

//字符串连接符  +  , 有一侧为String 就会转成字符串
int c = 10;
int d = 20;
System.out.println(""+c+d);  //输出结果为1020
System.out.println(c+d+"123");//字符串在后面,前面的还会运算,输出结果为30123

三元运算符

x ? y : z

如果x部分为true,则输出 y 部分,否则输出z部分

位运算

  • &:按位与
  • |:按位或
  • ^:异或运算,相同为0,不同为1
  • ~:非,按位取反
/*
A = 0011 1100
B = 0000 1101

A&B  0000 1100  按位与
A|B  0011 1101  按位或
A^B  0011 0001  异或  相同为0 不同为1
~B   1111 0010  非

2*8 = 16 2*2*2*2
<<左移 相当于乘2   >>右移相当于除以2
效率很高!
0000 0010  2
0000 0100  4
0000 1000  8
0001 0000  16
 */

程序控制流程

  • 顺序 选择 循环

switch控制流程

char grade = 'A';
switch (grade){         //switch有穿透现象,如果不写break,自匹配成功之后的所有分支都会输出
    case 'A':
        System.out.println("Good!");
    case 'B':
        System.out.println("Normal!");     //normal也会输出
        break;
    case 'C':
        System.out.println("Poor!");
}

jdk1.7后新特性:switch表达式可以为String

原理:字符的本质还是数字

反编译

Java源代码>>.class文件(字节码文件)>>Java程序

-------------------------------------------------------------------->编译

<------------------------------------------------------------------反编译

do-while与while

/*do{

  }while( )  至少执行一次
*/

/*while( ){

}  
*/

Scanner类

  • 凡是属于IO流的类如果不关闭会占用系统资源,要习惯性用完关闭

Scanner类:获取用户的输入

  • next()、nextLine():获取输入的数据
  • next():以空格作为分隔符,不能得到带有空格的字符串
  • nextLine():可以获得空格,以 Enter键结束
Scanner scanner = new Scanner(Systen.in);    //创建扫描器对象
String str = scanner.nextLine();			 //等待用户输入	
System.out.println(str);					 //输入输入的数据
scanner.close();							 //关闭扫描器对象
  • 判断是否还有输入的数据
  • hasNext():
  • hasNextLine():
 //创建一个扫描器对象,用于接受键盘数据
        Scanner scanner = new Scanner(System.in);

        System.out.println("使用next方式接收:");  

        //判断用户有没有输入字符串
        if(scanner.hasNext()){
            String str = scanner.next();  //程序会等待输入后再继续运行 
            System.out.println("输出内容为:"+str);
           	scanner.close();//凡是属于IO流的类如果不关闭会占用资源,养成好习惯用完关掉
        }
          

Scanner类常用方法

scanner.hasNext()、scanner.hasNextLine()、scanner.hasNextInt() 这些方法都是返回值类型为Boolean

scanner.next()、scanner.nextLine 获取字符串类型

scanner.nextInt()、scanner.nextDouble 获取整型、浮点型

Java方法

加一个static可以直接调用,不需要创建对象

/*
	修饰符  返回值类型 方法名(形参列表){
    
    方法体	
	
	return 返回值;  //return是方法执行的最后一个语句,return下面的语句不会执行	
	}


*/

递归

/*递归
    递归头:边界条件,即什么时候结束递归
    递归体:调用自身
 */
public static void main(String[] args) {
      System.out.println(f(5));
    }

static public int f(int n){
    if(n==1){                      
        return 1;                //边界条件
    }
    else {
        return n*f(n-1);         //调用自身
    }
}

重载

方法名相同,但是参数列表不同,形参类型不同/形参个数不同

println(),可以输入多种数据类型,用的就是方法的重载

判断两个方法是否相同:方法名是否相同,参数列表是否相同

数组Array

  • 使用注意事项

    1.数组存放相同数据类型(任意数据类型)
    2.数组也是对象 数组元素相当于对象的成员变量
    3.数组长度是确定的,不可变,注意不要越界

int[] numbs ; //数组声明,但是没有在堆中分配空间
numbs = new int[10] ;  //创建数组,在堆分配内存空间

int numbs1 = new int [10] ;  //声明+创建
初始化
//三种初始化方法

//静态初始化
int[] a = {1,2,3,4,5};

//动态初始化  包含默认初始化
int[] b = new int[5];

//默认初始化
//数组是引用类型,它的元素相当于实例变量,因此一旦分配空间,每个元素按照实例变量同样的方式被隐式初始化
增强for循环
int[] numbs= {10,20,30,40,50};
for(int x :numbs){
    System.out.println(x);
}
栈与堆
栈 stack
  • 存放基本数据类型 ,会存值
  • 存放引用对象在堆中的地址
  • Java中main()方法会在栈底,main()方法弹出后程序也就结束了
堆 heap
  • 存放new的对象和数组
  • 可以被所有线程共享,不会存放别的对象引用
方法区(也在堆中)
  • 可以被所有线程共享
  • 包括所有的class与static变量

栈堆内存图

面向对象编程(oop:object-oriented programming)

  • 面向对象编程的本质:以类的方式组织代码,以对象的形式封装数据
  • 三大特性:封装、继承、多态
  • 从认知论的角度说,是先有对象后有类。
  • 从代码运行角度说,是先有类,后有对象。类是对象的模板。
  • 静态方法static是和类一起加载(在静态方法区里),非静态方法是要类实例化(创建了对象)之后才存在
  • 值传递和引用传递:Java都是值传递

类与对象

  • 类是一个模板,对象是类的实例

  • 方法:定义、调用

  • 对应的引用

    • 引用类型: 除了8种基本类型
      • 对象是通过引用来操作的:栈----->堆(地址)
  • 属性:字段(field) 成员变量

    • 默认会初始化:
      • 数字:0 、 0.0
      • char:u0000
      • Boolean:false
      • 引用类型:null
    • 定义公式: 修饰符 属性类型 属性名 = 属性值 ;
  • 对象的创建和使用

    • 必须使用***new***关键字创建对象,调用构造器 Person zhangsan = new Person();
    • 对象的属性 zhangsan.name
    • 对象的方法 zhangsan.run()
    • 静态的属性 ---- 属性
    • 动态的行为 ---- 方法

new关键字

  • 使用new关键字来创建对象
  • 使用new关键字创建时,除了分配内存空间外,还会给创建好的对象进行默认的初始化,以及对类中构造器的调用
public class Student {
    //属性:字段
    String name; //默认值为null
    int age;    //0

    //方法
    public void stude(){
        System.out.println(this.name+"在学习");   //this关键字
    }
    
     //类型 类型名 = 类型值
     Student zhangsan = new Student();
     zhangsan.name  = "zhangsan";
     zhangsan.age  = 25;

构造器

  • 类中的构造器也被称为构造方法,是在进行创建对象的时候必须要调用的,

  • 构造器特点:

    • 1.必须和类名相同

    • 2.必须没有返回值类型,也不能写void

  • 构造器作用:

    • 1.new 关键字本质是在调用构造方法

    • 2.初始化对象值

  • 注意点:

    • 1.如果定义了有参构造,必须要显式定义无参构造
      • 即:不写的话会默认存在一个无参构造,写了有参构造后就这个无参构造就没了
    • 2.this. = 通常前面表示当前类,后面表示传进来的参数
    public class Person {
        String name;
        int age;
    
        //显式定义构造器
    
        //无参构造
        public Person(){
        }
    
        //有参构造:一旦定义了有参构造,无参就必须显式定义
        //构造方法的重载
        public Person(String name, int age) {
        this.name = name; //name为形参,this.name为对象属性的name
        this.age = age;
        }
     /*
            Person person = new Person();
            Person zhangsan = new Person("zhangsan",12);
      */
    
    

封装(数据的隐藏)

  • 属性私有,get/set
  • 高内聚,低耦合
  • 通常应该禁止直接访问一个对象中数据的实际表示,而应该通过操作接口来访问,这叫做信息隐藏

继承

  • 继承的本质是对一批类的抽象,从而实现对现实世界更好地建模

  • 关键字 extends:“扩展”。子类是父类的扩展

  • 子类与父类,在意义上具有“ is a” 的关系

  • 子类继承父类,就会有父类的全部的方法(public)

  • 私有的对象无法被继承

  • 四个权限:public protected default private

  • 在Java中,所有的类都直接或间接继承Object类

  • Java中只有单继承,没有多继承

super关键字

  1. super调用父类的构造方法,必须在构造方法的第一个
  2. super 必须只能出现在子类方法或者构造方法中
  3. super 和 this 不能同时调用构造方法

VS this

  • 代表的对象不同:
    • this:本身调用这个对象
    • super 代表父类对象的引用
  • 前提
    • this没有继承也可以使用
    • super只能在继承条件下才可以使用
  • 构造方法
    • this():本类的构造
    • super():父类的构造

方法重写

  • 前提:需要用继承关系,子类重写父类的方法!
    • 1.方法名必须相同
    • 2.参数列表必须相同
    • 3.修饰符:范围扩大: public>protected>default>private
    • 4.抛出的异常:范围:可以被缩小,但不能被扩大; ClassNotFoundException —>Exception(大)
  • 重写,子类的方法要和父类方法一致,方法体不同!
  • 为什么需要重写?
    • 父类的功能,子类不一定需要,或者不一定满足

方法重写:子类方法与父类方法一模一样 子类继承父类才能重写,子类重写父类的方法

方法重载:参数名不一样,相当于是本类的

静态方法:方法的调用只和左边,定义的数据类型有关,与重写无关

多态

动态编译:类型:可扩展性

方法的多态,属性没有多态

抽象(编程思想):封装、继承、多态 抽象类 、接口,

父类型的引用指向子类型的对象

  • 子类转换为父类,向上转型,自动,丢失子类中特有的方法
  • 父类转换为子类,向下转型,强转,丢失父类被子类重写过的方法
  • 方便方法的调用,减少重复的代码

同一个方法可以根据发送对象的不同而采取多种不同的行为方式

一个对象的实际类型是确定的,但是可以指向对象的引用的类型可以非常多(父类,有关系的类)

  • 注意事项
    • 方法的多态,属性没有多态
    • 父类和子类,有联系 类型转换异常ClassCastException
    • 存在条件:继承关系,方法需要重写,父类的引用是指向的子类对象 Father f1 = new Son();
      • 不能被重写的方法: 自然没有多态
        • 1.static 方法,属于类,不属于实例
        • 2.final 常量;
        • 3.private方法;

instanceof关键字

X instanceof Y :X所指向的实际类型,是不是Y类型的子类型,如果是则返回ture,否则返回false

引用类型转换

  • 基本类型转换:高---->低 强转 丢失精度
  • 引用类型转换:父----->子 强转
Person obj = new Student();

//将student对象转成Student类型,就可以使用Student类型方法了
Student student = (Student2)obj;   //obj类型强转,高转低
student.go();    //go()方法为Student子类里的方法
//((Student2)obj).go();

//子类转父类  可能丢失自己的一些方法
Person2 person2 = obj;
//obj.go;不可以

static关键字

  • 被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) {
        Person0 person0 = new Person();
        System.out.println("==========================");
        Person0 person1 = new Person();
    }
}
/*
静态代码块
匿名代码块
构造方法
==========================
匿名代码块
构造方法
*/

静态导入包

import static java.lang.Math.random;
import static java.lang.Math.PI;
public class Test{
    System.out.println(random());
    System.out.println(PI);
}

抽象类

abstract关键字,声明抽象类/抽象方法,extens去继承实现

  • 抽象类是一种约束,抽象方法只有方法名,没有方法体
  • 抽象类中的抽象方法,必须由继承它的子类实现,除非子类仍然是抽象类*
  • 不能new抽象类,只能靠子类来实现
  • 抽象类可以写普通方法,但是抽象方法必须在抽象类中

接口(interface)

interface定义接口,implements实现,可以进行多继承

普通类:只有具体实现

抽象类:具体实现和规范(抽象方法)都有

接口:只有规范,自己无法写方法 约束和实现分离:面向接口编程

接口的本质是契约

  • 接口就是规范,定义的是一组规则
  • OO的精髓,就是对于对象的抽象,最能体现这一点的,就是接口
  • 设计模式所研究的,就是如何合理地去抽象

作用:

  1. 约束
  2. 定义一些方法,让不同的人实现
  3. 方法都是public abstract
  4. 常量都是public static final
  5. 接口不能被实例化,接口中没有构造方法
  6. 可以实现多个 implements
  7. 必须重写接口中的方法
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);
}
public interface TimeService {
    void timer();
}
//接口实现,使用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() {

    }
}

内部类

  • 内部类就是在一个类中,又定义了一个类
  • 一个Java类中可以有多个class类,但是只能有一个public class
public  class Outer {
    private int id = 10;
    public void out(){
        System.out.println("这是外部类的方法");
    }
    //局部内部类
     public  class Inner {
        public void in(){
            System.out.println("这是内部类的方法");
        }
        //内部类可以获得外部类的私有属性
        public void getId(){
            System.out.println(id);
        }
    }
}

//main()方法
		Outer outer = new Outer();
        //通过这个外部类来实例化内部类
        Outer.Inner inner = outer.new Inner();
        inner.in();
        inner.getId();

异常机制Exception

  • 检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
  • 运行时异常:运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
  • 错误ERROR:错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。

在Java中,把异常当作对象处理,定义了一个java.lang.Throwable作为所有异常的超类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gdGxx8ep-1631541857856)(E:\Note\Java异常处理.PNG)]

可以分成运行时异常与非运行时异常

  • Error与Exception的区别:Error通常是灾难性的致命错误,是程序无法控制和处理的。当出现这些异常时,Java虚拟机(JVM)会终止线程。Exception通常情况下是可以被程序处理的,并且在程序中应该 尽可能的去处理这些异常。
    异常处理

异常处理五个关键字

  • try:监控区域
  • catch:捕获异常
  • finally:无论是否有异常都要执行
  • throw:主动抛出异常
  • throws:方法中处理不了异常,方法上抛出异常
public static void main(String[] args) {
    int a = 1;
    int b = 0;

    try{//try监控区域    一般try与catch连用
    if (b==0){
    throw new ArithmeticException();//主动抛出异常
    }
    System.out.println(a/b);
    }catch(Error e) {  //catch(想要捕获的异常类型,最高为Throwable)
    System.out.println("Error");
    }catch(Exception e){
    System.out.println("Exception");
    }
    catch(Throwable e){//范围要从小到达,否则下面的小范围异常类型会被上面的大类型覆盖
    System.out.println("Throwable");
    }
    finally{//finally一般用来处理善后工作  无论是否出异常都会执行   可以不要finally   假设IO,资源,关闭!
    System.out.println("finally");
    }
}

实践经验

  • 处理运行时异常时,采用逻辑去合理规避同时辅助try-catch处理
  • 在多重catch后面,可以加一个catch(Exception)来处理可能会被遗漏的异常
  • 对于不确定的代码,也可以加上try-catch,处理潜在异常
  • 尽量去处理异常,切忌只是简单地调用printStackTrace()去打印输出
  • 具体如何处理异常,要根据不同的业务需求和异常类型去决定
  • 尽量添加finally语句块去释放占用的资源 IO流用到的比较多

自定义异常(较少用到)

用户自定义异常类,只需要继承Exception类即可。

创建自定义异常类步骤:

  1. 创建自定义异常类
  2. 在方法中通过throw关键字抛出异常对象
  3. 如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出方法给调用者的异常,继续进行下一步操作。
  4. 在出现异常方法的调用者中捕获并处理异常。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值