Javase学习笔记2023.10.10

2023年java学习笔记

Java基础语法


数据类型

基本数据类型:

若需要一整型字面量默认是long型,可在后面加上L / l;

若需要一小数字面量默认是float型,可在后面加上F / f;

类型转换

自动类型转换

自动类型转换的其他形式:

byte  --> short or char --> int --> long --> float -->double 

表达式的自动类型转换

1.表达式的最终表达结果类型由表达式中的最高类型决定;

2.在表达式中,byte、short、char 是直接转换int类型参与运算的。

强制类型转换

注意类型范围大的数据或变量,直接赋值给类型范围小的变量会报错。

package com.it.hello;
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println((char)('a'+10));
    }
}

注意事项:

强制类型转换可能造成数据(丢失)溢出;

浮点型强转成整型,丢失小数部分,保留整数部分返回。

运算符

基本的算数运算符

package com.it.hello;

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println(10 % 3); // 1
        System.out.println(10 / 3); // 3
    }
}

“+”符号作连接符:“+”符号与字符串运算时作连接符,其结果仍然是一个字符串。

自增自减运算符

注意++,--只能操作变量,不能操作字面量。

package com.it.hello;

public class HelloWorld {
    public static void main(String[] args) {
        int a = 5;
        System.out.println(++a); //先执行a+1,再输出新的a
        System.out.println(a++); //输出a,再执行a+1
    }
}

赋值运算符

package com.it.hello;

public class HelloWorld {
    public static void main(String[] args) {
        int a = 5;// 从右往左看,把数据5赋给变量a储存
    }
}

注意:拓展的赋值预算符隐含了强制类型转换

关系运算符

用于判断数据是否满足条件,最终返回一个判断的结果,返回值的类型是布尔值:true或false。

逻辑运算符

在java中,"&"、"|",无论左边是true还是false,右边都执行

&& 和 || 效率更高

三元运算符、运算符的优先级

" * "、"/"的优先级高于"+"、"-"

&&优先级高于 ||

package com.it.hello;

public class HelloWorld {
    public static void main(String[] args) {
        int a = 3,b = 5;
        System.out.println(10>3 || 10 > 3 && 10 < 3);// true
    }
}

"( )"优先级最高         

Scanner接收键盘输入数据

package com.it.hello;

import java.util.Scanner;

public class HelloWorld {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        // 调用sc的功能,来接收用户从键盘输入的数据
        int age = sc.nextInt();// 执行到这,会开始等待用户输入一个整数,直到用户输入换行(回车),才会拿到数据
        System.out.println(age);
    }
}

流程控制

分支结构

if

根据条件(真或假)来执行某段代码。

若不满足条件1,判断条件2,向下依次判断条件,如果都不满足,执行else部分代码。  

if语句中常见问题:

1.if(条件)后不能跟" ; ",否则{ }中的代码不受if控制。

2.如果if中语句中只有一行代码,{ }可以省略不写。(不推荐省略)

switch

switch(表达式){
    case值1:
        执行代码...;
        break;
    case值2:
        执行代码...;
        break;
    ...
    ...
    case值n:
        执行代码...;
        break;
    default:
        执行代码...;
}
    

if与switch比较:

1.if在功能上强于switch

2.当前条件是区间时,应该使用if分支结构

3.当条件是一个一个值比较时,switch分支结构更好:格式良好,性能较高,代码优雅

利用switch的穿透性,在某些情况下可以简化代码:当存在多个分支的代码相同时,可以把相同的代码放到一个case块中,其他的case块都通过穿透性穿透到该case块执行代码即可,这样可以简化代码

循环结构

for循环

//输出3次Hello World

for(int i = 0 ; i < 3 ; i++){
    System.out.println("Hello World")
}

执行流程:

while循环

//打印3次Hello World
int i = 0;
while(i < 3){
    System.out.println("Hello World");
    i++;
}

执行流程:

知道循环几次使用for,不知道循环几次建议用while。

do-while循环

do-while执行特点:

先执行后判断

死循环

for( ; ; ){
    System.out.println("Hello World1");
}

//经典写法
while(true){
    System.out.println("Hello World2");
}

do(
    System.out.println("Hello World3");
}while(true)

可以一直执行下去的循环,如果没有干预不会停止执行.

循环嵌套

循环中又包含循环

//输入15次Hello World
for(int i = 0 ; i < 5 ; i ++){
    for(int j = 0 ; j < 3 ; j++){
        System.out.println("Hello World");
    }
}

跳转关键字:break,continue

Random的使用

import java.util.Random;

public class HelloWorld {
    public static void main(String[] args) {
        //创建一个random对象,用于生成随机数
        Random r = new Random();
        //调用Random提供的功能nextInt得到随机数
        int data = r.nextInt(10);// 0-9
        System.out.println(data);
    }
}

数组

静态初始化数组

数组的访问

数组的遍历

遍历就是一个一个数据的访问

//遍历ages
int ages[] = {15,18,20};
int Length = ages.length;
for(int i = 0 ; i < Length ; i++){
    System.out.println(ages[i]);
}

动态初始化数组

方法

方法的其他形式

Java的参数传递机制

基本类型的参数传递

引用类型的参数传递

面向对象编程基础

开发一个一个的对象,把数据传输给对象,再调用对象的方法完成对数据的处理。

package com.it.object;

public class Test {
    public static void main(String[] args) {
        Student s1 = new Student();
        s1.name = "小虎";
        s1.Chinese = 100;
        s1.Math = 130;
        s1.PrintTotalScore();
    }
}
package com.it.object;

public class Student {
    String name;
    double Chinese;
    double Math;

    public void PrintTotalScore(){
        System.out.println(name + "各科的总分是:" + (Chinese + Math));
    }

}

认识面向对象

1.面向对象编程符合人类思维,编程更简单,更直观

2.对象本质上是一种特殊的数据结构

3.class也就是类,也称为对象的设计图(或对象的模板)。

类和对象的一些注意事项

this

this就是一个变量,可以用在方法中,来拿到当前对象。

package com.it.object;

public class Student {
    public void PrintThis(){
        System.out.println(this);
    }
}
package com.it.object;

public class Test {
    public static void main(String[] args) {
        Student s1 = new Student();
        System.out.println(s1);
        s1.PrintThis();
    }
}

输出结果:

this主要用来解决变量冲突问题

构造器

创建对象时,对象会去调用构造器

public class Student {
    //无参数构造器
    public Student(){

    }
    //有参数构造器
    public Student(String name){

    }
}

构造器的常见应用场景

创建对象时,同时完成对对象成员变量(属性)的初始化赋值

package com.it.object;

public class Student {
    String name;
    double score;
    public Student(String name,double score){
        this.name = name;
        this.score = score;
    }
}
package com.it.object;

public class Test {
    public static void main(String[] args) {
        Student s1 = new Student("小虎",100);
        System.out.println(s1.name);// 小虎
        System.out.println(s1.score);// 100
    }
}

构造器的注意事项

封装

什么是封装?

封装就是用类设计对象处理某一个事物的数据是,应该把要处理的数据,以及处理这些数据的方法,设计到一个对象中去

封装的设计规范:合理隐藏,合理暴露

public class test {
    String name;// 都可访问
    private double score; //私有访问
}

实体javaBean(实体类)

什么是实体类?

实体类就是一种特殊类

1.这个类中的成员变量都要私有,并且要对外提供相应的getxxx,setxxx方法

public class test{
    private double number;// 私有数据
    public void SetNumber(double temp){
        this.number = temp;
    }
    public double GetNumber(){
        return this.number;
    }
}

2.类中必须有一个公共的无参的构造器

实体类应用场景

常用API

API全称Application Programming Interface(应用程序接口)

就是调用别人写好的程序来解决问题

String

调用java.lang.String

String使用时的注意事项

1.String对象的内容不可改变,被称为不可改变字符串对象

每次试图改变字符串对象实际上是产生了新的字符串对象,变量每次都是指向了新的字符串对象,之前字符串的内容始终没有改变,因此称String的对象是不可变的

2.只要是以”...."方式写出的字符串对象,会存储到字符串常量池,且相同内容的字符串只存储一份。但通过new方式创建字符串对象,每new一次都会产生一个新的对象放在堆内存中。

ArrayList

ArrayList代表一种集合。

集合是一种容器,用来存储数据,类似于数组。不同于数组,数组定义完成并启动后,长度固定,而集合大小可变。

面向对象高级

Static

Static修饰成员变量

static叫静态,可以修饰成员变量、成员方法。

成员变量按照有static修饰分为两种:

类变量(静态成员变量):有static修饰,属于类,在计算机中只有一份,会被类的全部对象共享

实例变量(对象的变量):无static修饰,属于每个对象

package com.it.object;

public class Student {
    static String name;
}
package com.it.object;

public class Test {
    public static void main(String[] args) {
        Student.name = "Tim";

        Student s1 = new Student();
        s1.name = "Tom";

        Student s2 = new Student();
        s2.name = "TimTom";

        System.out.println(s1.name); // TimTom
    }
}

Static修饰成员方法

类方法:有static修饰的成员方法,属于类

实例方法:无static修饰的成员方法,属于对象

Static的注意事项

代码块

单例设计模式

单例设计模式:确保一个类只有一个对象

写法:

1.把类的构造器私有

2.定义一个类变量记住类的一个对象

3.定义一个类对象,返回对象

package com.it.object;

public class Student {
    //定义一个类变量记住类的一个对象
    private static Student Stu = new Student();

    //必须私有类的构造器
    private Student(){

    }
    //定义一个类方法返回类的对象
    public static Student GetObject(){
        return Stu;
    }
}

继承

继承相关的注意事项

权限修饰符

权限修饰符就是用来限制类中的成员(成员变量、成员方法、构造器、代码块)能够被访问的范围。

单继承、Object

Java是单继承的,Java中的类不支持多继承,但是支持多层继承

Object类是java所有类的祖宗类,我们写的任意一个类,实际上是object的子类或子孙类

方法重写

子类根据需求重写一个方法名称、参数列表一样的方法,去覆盖父类的方法,这就是方法重写

注意:重写后,方法的访问,java会遵循自动原则

方法重写的注意事项:

  • 使用Override注解,可以指定java编译器,检查我们方法重写的格式是否正确,代码可读性也会更好。
  • 子类重写父类方法时,访问权限必须大于后者等于父类该方法的权限(public > protected > 缺省)
  • 重写的方法返回值类型,必须与被重写方法的返回值类型一样,或者范围更小
  • 私有方法、静态方法不能被重写

子类访问其他成员的特点

子类访问其他成员(成员变量、成员方法),是遵循就近原则

  • 先子类局部范围找
  • 然后子类成员范围找
  • 然后父类范围找,如果父类没找到则报错

如果子父类中,出现重名的成员,会优先使用子类如果需要使用父类可以通过super关键字指定访问父类的成员:super.父类成员变量/成员方法

子类构造器的特点

子类的全部构造器,都会先调用父类的构造器,再执行自己。

子类构造器是如何实现调用父类构造器的:

  • 默认情况下,子类全部构造器的第一行代码都是super()(写不写都有),它会调用父类的无参数构造器
  • 如果父类没有无参数构造器,则我们必须在子类构造器的第一行手写super(...),指定去调用父类的有参数构造器

补充:this(...)调用兄弟构造器:

任意类的构造器中,是可以通过this(...)去调用该类的其他构造器的

面向对象的三大特征之三:多态

认识多态

多态是在继承/实现情况下的一种现象,表现为:对象多态、行为多态

使用多态的好处

  • 在多态形式下,右边对象是解耦合的,更便于拓展和维护
  • 定义方法时,使用父类类型的形参,可以接受一切子类对象,拓展性更强,更便利

多态下的类型转换问题

  • 自动类型转换:父类 变量名 = new 子类();
  • 强制类型钻换:子类 变量名 = (子类) 父类变量

注意事项:

  • 存在继承/实现关系就可以在编译阶段进行强制类型转换,编译阶段不会报错
  • 运行时,如果发现对象的真实类型与强转后的类型不同,就会报类型转换一场(ClassCastException)的错误出来。

强转前使用instanceof关键字,判断当前对象的真实类型,再进行强转

p1 instanceof Test //返回True或False

final

认识final

final关键字是最终的意思,可以修饰(类,方法,变量)

  • 修饰类:该类称为最终类,不能被继承了
  • 修饰方法:该方法称为最终方法,特点是不能被重写了
  • 修饰变量:该变量只能被赋值一次

final修饰变量的注意:

  • final修饰基本类型的变量,变量存储的数据不能改变
  • final修饰引用类型的变量,变量存储的地址不能被改变,但地址所指向的内容是可以被改变的

常量详解:

使用了static final修饰的成员变量就称为常量

作用:通常用于记录系统的配置信息

public static final String TEST_NAME = "This is a test"

常量名命名规范:使用大写英文单词,多个单词使用下划线连接

使用常量记录系统配置信息的优势、执行原理:

  • 代码可读性更好,可维护性也更好
  • 程序编译后,变量会被“宏替换”:出现常量的地方全部会被替换成其记住的字面量,这样可以保证使用常量和使用字面量的性能是一样的

抽象类

认识抽象类

abstract关键字(抽象),可以修饰类、成员方法

abstract修饰类,这个类就是抽象类;修饰方法,这个方法就是抽象方法

抽象类的注意事项、特点:

  • 抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
  • 类该有的成员(成员变量、方法、构造器)抽象类都可以有
  • 抽象类最主要特点:抽象类不能创建对象,仅作为一种特殊的父类,让子类继承并实现
  • 一个类继承抽象类,必须重写完抽象类的全部抽象方法,否则这个类也必须定义为抽象类

抽象类的好处

  • 父类知道每个子类都要做某个行为,但每个子类做的情况不一样,父类就定义抽象方法,交给子类去重写实现,这样就是为了更好的支持多态

抽象类常见应用场景:模板方法设计模式

模板方法设计模式解决方法中存在重复代码的问题

接口

JAVA提供一个关键字interface,用这个关键字我们可以定义一个特殊的结构:接口

public interface 接口名{
    //成员变量 (常量)
    //成员方法 (抽象方法)
}

接口不能创建对象;接口是用来被类实现(implements)的,实现接口的类称为实现类

一个类可以实现多个接口,实现类实现多个接口,必须全部重写完全部接口的全部抽象方法,否则实现类需要定义成抽象类

接口的好处

  • 弥补了类单继承的不足,一个类同时可以实现多个接口
  • 让程序可以面向接口编程,这样程序员就可以灵活方便的切换各种业务实现
package com.it.hello;

public class test {
    public static void main(String[] args) {
        Singer s =new A();
    }
}

class A extends Student implements Drivers, Singer{

    @Override
    public void drive() {

    }

    @Override
    public void sing() {

    }
}

class Student{

}

interface Drivers{
    void drive();
}

interface  Singer{
    void sing();
}



一个接口可以继承多个接口

注意事项:

  • 一个接口继承多个接口,如果多个接口中存在签名冲突,则此时不支持多继承
  • 一个类实现多个接口,如果多个接口中存在方法签名冲突,则此时不支持多实现
  • 一个类继承了父类,有同时实现了接口,父类和接口中有同名的默认方法,实现类会优先用父类的
  • 一个类实现了多个接口,多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可
interface I{
    void test1();
}

interface J{
    String test1();
}

//一个接口继承多个接口,如果多个接口中存在签名冲突,则此时不支持多继承
interface K extends I,J{ 
    //
}

一个类实现多个接口,如果多个接口中存在方法签名冲突,则此时不支持多实现
class E implements I,J{
    //
}

内部类

内部类是类的五大成员之一(成员变量、方法、构造器、内部类、代码块),如果一个类定义在另一个类的内部,这个类就是内部类

使用场景:当一个类的内部,包含了一个完整的事物,且这个事物没有必要单独设计时,就可以把这个事物设计成内部类

内部类四种形式:成员内部类、静态内部类、局部内部类、匿名内部类

成员内部类:

Outer.Inner in = new Outer.new Inner();

成员内部类可以访问外部类的实例成员、静态成员

静态内部类

又static修饰的内部类,属于外部类自己持有

可以直接访问外部类的静态成员,不可以访问外部类实例成员

匿名内部类

是一种特殊的局部内部类;所谓匿名,指的是程序员不需要为这个类命名

new 类或接口(参数值...){
    类体(一般是方法重写);
};
public class test {
    public static void main(String[] args) {
        Animal a = new Animal(){
            @Override
            public void cry() {
                System.out.println("喵喵喵");
            }
        };
        a.cry();
    }
}

abstract class Animal{
    public abstract void cry();
}

特点:匿名内部类本质就是一个子类,并会立即创建出一个子类对象

作用:用于更方便的创建一个子类对象

匿名对象类通常作为一个参数传输方法

枚举

枚举是一种特殊类。

枚举类的格式:  

修饰符 enum 枚举类名{
    名称1,名称2,...;
    其他成员...
}

public enum A{
    X , Y , Z;
    ...
}

注意:

  • 枚举类的第一行,只能写一些合法的标识符,多个名称用逗号隔开
  • 这些名称,本质上是常量,每个常量都会记住枚举类的一个对象
  • 枚举类的构造器都是私有的,因此枚举类对外不能创造对象
  • 枚举都是最终类,不可以被继承
  • 枚举类中,从第二行开始,可以定义类的其他成员

枚举的常见应用场景:

用来表示一组信息,然后作为参数进行传输

泛型

定义类、接口、方法时,同时声明了一个或者多个类型变量(如:<E>),称为泛型类、泛型接口、泛型方法,他们统称为泛型

ArrayList<String> list1 = new ArrayList<>();

作用:泛型提供了在编译阶段约束所能操作的数据类型,并自动检查的能力!这样可以避免强制类型转换,及其可能出现的异常

泛型的本质:把具体的数据类型作为参数类传递给类型变量

泛型类

修饰符 class 类名<类型变量,类型变量,...>{

}

public class Arraylist<E>{
    ...
}

泛型接口

public interface A<E>{
    ...
}

泛型方法

泛型的擦除问题和注意事项

  • 泛型是工作在编译阶段的,一旦程序编译成class文件,class文件中就不存在泛型了,这就是泛型擦除
  • 泛型不支持基本数据类型,只能支持对象类型(引用数据类型)

常用API

Object

Object类是Java所有类的祖宗类,因此Java的所有对象一直接使用Object类提供的一些方法

@Override
public String toString() {
    return "Student{" +
    "name='" + name + '\'' +
    ", age=" + age +
    '}';
}

包装类

StringBuilder

StringBuilder代表可变字符串对象,相当是一个容器,他里面装的字符串是可以改变的,就是用来操作字符串的。

好处:StringBuilder比String更适合做字符串的修改操作,效率更高,代码更简洁

StringBuffer与StringBuilder

StringBuffer与StingBuilder用法相同,但StringBuffer是线程不安全的,StringBuffer是线程安全的

StringJoiner

Math

System

System代表程序所在的系统,也就是一个工具类

Runtime

代表程序所在的运行环境,Runtime是一个单例类

BigDecimal

BigDecimal

Date

SimpleDateFormat

JDK8新增时间

Arrays

用来操作数组的一个工具类

Lambda表达式

Lambda是JDK8以后新增的语法形式,用于简化匿名内部类写法

方法引用

静态方法的引用

正则表达式

public class Main {
    public static void main(String[] args) {
        System.out.println(checkQQ("123124124"));
    }
    public static boolean checkQQ(String qq){
        //1.判断qq是否为空或非法
        if(qq == null || qq.startsWith("0") || qq.length() <6 || qq.length() > 20){
            return false;
        }
        //2.判断qq号码是否都为数字
        for (int i = 0; i < qq.length(); i++) {
            //根据索引提取当前位置处的字符
            char ch = qq.charAt(i);
            //判断ch记住的字符,如果不是数字,qq号码不合法
            if(ch < '0' || ch > '9'){
                return false;
            }
        }
        //qq号码合法
        return true;
    }
}

使用String的matches方法

public class Main {
    public static void main(String[] args) {
        System.out.println(checkQQ("123124124"));
    }
    public static boolean checkQQ(String qq) {
        return qq != null && qq.matches( "[1-9]\\d{5,20}");
    }
}

书写规则

string提供了一个匹配正则表达式的方法

public boolean matches(String regex) //判断字符串是否匹配正则表达式,匹配返回true,不匹配返回false

代码演示:

public class Main {
    public static void main(String[] args) {
        System.out.println("a".matches("[abc]")); //[abc]只能匹配abc
        System.out.println("e".matches("[^abc]")); // [^abc]不能是abc
        System.out.println("b".matches("[a-zA-Z]")); // [a-zA-Z] 只能是a-z A-Z的字符
        System.out.println("a".matches("[a-z&&[^bc]]"));// a到z,除了b和c
        //以上只能匹配单字符

        //2.预定义字符(只能匹配单个字符)
       /*
        \d 任意字符
        \s表示一个空白字符
        \S代表一个非空白字符
        \w : [a-zA-Z_0-9]
        \W : 不能是a-zA-Z_0-9
        */
//-------------------------------------
        //3.数量词
        /*
        ? 代表0次或1次
        * 代表0次或多次
        + 代表1次或多次
        {n} 代表正好是n次
        {3,} 代表>=3次
        {3,9} 代表大于等于3次,小于等于9次
        */
        System.out.println("abc123ll".matches("\\w{3,9}"));

        //4.其他几个常用符号: (?i)忽略大小写    或: |      分组:()
        System.out.println("aBc".matches("a((?i)b)c"));
    }

}

异常

认识异常

异常就是程序出现的问题

 自定义异常

import com.sun.tools.attach.AgentInitializationException;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.Callable;

public class Main {
    public static void main(String[] args){
        try {
            savaAge(160);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public static void savaAge(int age){
        if(age > 0 && age <150){
            System.out.println("succeed");
        }
        else{
            throw new AgeIllegalRuntimeException("Age is illegal");
        }
    }
}
public class AgeIllegalRuntimeException extends RuntimeException {
    public AgeIllegalRuntimeException(){

    }

    public AgeIllegalRuntimeException(String message) {
        super(message);
    }
}

异常的处理方式

集合进阶

Collection的常用方法

Collection的遍历方式

        迭代器

        

Lambda表达式遍历集合

List集合

特点、特有方法

List集合特点:有序、可重复、有索引

  • ArrayList:有序、可重复、有索引
  • LinkedList:有序、可重复、有索引

​​​​​​​

遍历方式

LinkList

数据进入栈模型的过程称为:压/进栈(push)

数据离开栈模型的过程称为:弹/出栈(pop)

Set集合

特点

HashSet的底层原理

LinkedHashSet

TreeSet集合

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值