Java基础学习笔记1

引言
  本文写作的目的是记录学习Java基础知识的过程中遇到的一些重要的知识点,这些知识点可以是API、死记硬背的东西、不经常出现但是对深入理解Java有很大帮助的话。我学习Java过程只参考https://how2j.cn/网站,讲的很多东西都是实用的,但是相比于书本来说肯定是不够全面的。因此,在学习过程中需要经常思考,并且常看评论区,然后百度得到答案。
  本文的笔记涉及的Java知识范围包括变量、操作符、控制流程、数组、类和接口、数字与字符串、日期
  我距离第一次学完已经过了很长时间,也自己开发了Java系统,这个过程是对Java基础的温故知新。因此,现在正好有时间将我记录下的一些重要笔记发到博客中,希望能帮助到一些同样学习Java基础的人。在后面遇到新的东西也会经常来更新博客,大家有什么问题或新的见解可以在评论区回复。

一、变量

1.下面列出了基本类型的数据范围,在IDE中给变量赋值超出范围会出现编译错误
整型数据范围
浮点型数据范围
2.String不是基本数据类型,基本类型包括byte、short、int、long、float、double、boolean、char,并且它们都有对应的封装类。通过“=”将基本类型转换为封装类的过程叫装箱,反之叫拆箱

3.整型变量都可以直接通过范围内的整数赋值,并支持各种进制;而浮点变量赋值默认为double,为float变量赋值必须在小数后加f
变量赋值
4.short和char同样是16位,但是彼此进行赋值还是需要强制转换。大精度给小精度赋值时,可以进行强制转换,但是有风险(可能转换之后就变成了负数)

5.整型数据进行运算时,只要它们的类型<=int,结果就是一个int型;如果有long型变量,结果就是long
变量运算的结果类型
6.final关键字的作用:
①修饰类:不能被继承
②修饰方法:不能被重写
③修饰变量:只有一次赋值的机会,可以在定义时赋值,或者后面再赋值
④修饰引用:只有一次指向的机会,但指向的对象的内容可以随意修改

7.变量的作用域遵循就近原则,使用的是在可见范围内距离当前同名变量中最近的一个

二、操作符

8.因为整型数据是有正负的,所以除了无符号右移“>>>”外,其他的位操作符都可能得到负数,有符号右移“>>”会保留正负数属性。一个数乘以2的次幂,相当于这个数左移[次幂]位,例如a * 8 = a * 2^3,相当于a左移3位,这个特点在LeetCode题目中也会见到
左移过程
左移结果

9.使用Scanner读取用户输入的数据时,除了nextLine()会以回车作为结束符外,其余的都是以空白符为结束符。nextLine()会读取到残留的回车,因此需要用两次nextLine()来消除回车的影响。比如用户输入了两行数据:
12345
上山打老虎
第一行数据可以用一个int型变量来接收:int a = scanner.nextInt();
这时候就会残留一个回车和一段字符串,为了获取字符串,可以使用两次nextLine()函数:scanner.nextLine(); String str = scanner.nextLine();
第一次nextLine()得到一个回车符,第二次nextLine()才会得到完整的字符串(同时也包含了第二行的回车符)

三、控制流程

10.switch支持byte、short、int、char、String、enum,其中判断String是通过hash实现的,可以理解为字面值,而不是引用

11.使用标签结束外部循环(注意冒号)

public class Main{
	public static void main(String[] args){
		out:
		for (int i = 0; i < 10; i++){
			for (int j = 0; j < 10; j++){
				if (j % 2 == 0){
					break out;
				}
			}
		}
		System.out.println("退出外部循环");
	}
}

四、数组

12.初始化一个数组可以使用arr = new int[length]或arr = new int[]{a,b,c}或arr = {a,b,c},第一种方式初始值全为0。如果指定了长度length就不能使用{}赋初值,只能在后续程序中一个个填充

13.Arrays类的静态方法:

int[] tmp = Arrays.copyOfRange(int[] original, int from, int to);    /复制数组内容,to取不到
String content = Arrays.toString(a);         //将数组a的内容转换为字符串
Arrays.sort(a);     //对数组a进行排序(默认升)
Arrays.equals(a, b);      //比较数组的内容是否一样,若比较数组是否一样用"=="
与第一个方法有相同作用的数组复制方法还有一个:System.arraycopy(src, srcPos, dest, destPos, length)

数组复制参数

五、类和接口

14.方法重载要求参数列表不同,包括数量、类型、顺序。可变数量的参数用三个点表示,必须放在列表最后,被当做数组使用

public void func(int a, double b, String...strings) {
    for (int i = 0; i < strings.length; i++) {
        System.out.println(strings[i]);
    }
}

15.基本类型参数传递的是副本,而类参数传的是对象(不是引用)。修改了形参的指向,不会影响实参的指向;但修改对象的内容,两者指向的对象都会变化

16.类属性或方法用static声明,并且只能在static声明的方法中使用,例如Main函数。在一个静态方法内,不能使用非静态字段或非静态方法,因为它们都是跟对象关联的,没有对象就不能调用

17.属性的初始化有三种方式,分别是声明时赋值、块赋值、构造函数赋值。在程序运行时执行顺序是:静态赋值初始化、静态块初始化、普通赋值初始化、普通块初始化、普通构造函数初始化

public class Test{
	private static int day = 7;
	static {
		System.out.println(day); 
		day = 6;
		System.out.println(day); 
	}
	private int month = 12;
	{
		month = 11;
	}
	public Test(){
		month = 10;
	}
	
	public static void main(String[] args) {
        Test test = new Test();
		System.out.println(test.month); 
		System.out.println(Test.day); 
    }
}

//  输出7 6 10 6

18.单例模式:构造函数私有化、静态私有引用指向该类实例、提供一个静态公有方法获取该实例。单例模式有饿汉式和懒汉式,区别在于启动时,饿汉会加载实例,速度稍慢;懒汉式在第一次使用实例时才会创建

19.枚举类存放一些同类型的常量,全部大写并且用“,”分隔。这些常量对应的默认整数从0开始递增,可以用"V(num)"的形式定义常量V对应的整数,但是要在这个枚举类中定义一个编号变量(例如seq),并且提供构造函数和获取编号的方法(可选)

public enum Season {
    SPRING(1),
    SUMMER(2),
    AUTUMN(4),
    WINTER(8);

    private int seq;
    Season(int seq){
        this.seq = seq;
    }
    public int getSeq() {
        return this.seq;
    }
}

20.ref instance of class:判断一个引用ref指向的对象是否属于class类或其子类

21.父类的非static方法可以被子类继承和重写,当一个父类引用指向子类对象并调用该方法时,会发挥子类重写后的作用;父类的static方法可以被子类继承或隐藏(重写的意思),当一个父类引用指向子类对象并调用该方法时,还是发挥父类的作用,但是一般不用对象来调用静态方法

// 父类
public class Animal {
    public static void func1(){
        System.out.println("父类静态方法");
    }
    public void func2(){
        System.out.println("父类普通方法");
    }
}

// 子类
public class Cat extends Animal{
    public static void func1(){
        System.out.println("子类静态方法");
    }
    @Override
    public void func2(){
        System.out.println("子类普通方法");
    }
}

// 测试
public static void main(String[] args) {
    Cat cat = new Cat();
    Animal animal = cat;
    animal.func2();
    animal.func1();
}

// 输出
子类普通方法
父类静态方法

22.this和super的总结:
①this的本质是已创建对象的内存地址,代表调用方法、属性、构造方法的当前对象。当this要在构造函数中使用时,必须放在第一行,且只能有一个。例如在一个有参构造函数中调用一个无参构造函数,则this();要放在第一行
②super是父类的引用,存储着隐藏的父类对象。可以用super.xxx调用父类的属性、方法。而super()表示调用父类的构造函数,如果不显式指定,编译器会默认调用,此时如果父类没有无参构造函数,那么就会报错,所以可以显式调用super(xx,xx)等有参构造方法来初始化父类对象。同样地,调用父类构造函数要放在子类构造函数的第一行
③super() or this()都要放在构造函数的第一行,而且不能同时存在,super一定时存在于this调用的最后一个环节。执行顺序就像是递归调用一样的,先入栈的是子类最先被调用的构造函数,最后入栈的也是最先执行的,即Object()
④this和super都是指对象,所以无法用在static方法中

23.Object是所有类的父类,为所有类提供一些默认方法,可以直接重写:toString、finalize、equals、hashCode、wait、notify、notifyAll、getClass

24.Java抽象类可以对属性进行静态/非静态、final的定义,可以有非抽象方法并有方法体。接口可以有属性,但是它的属性必须是public static final定义并初始化的,也就是一个常量,默认方法可以有方法体,在方法最开头用default定义

25.内部类分为4种:非静态内部类、静态内部类、匿名类(常用)、本地类。前两个的定义与外部类的属性/方法等地位相同,可以理解为与外部类绑定在一起的有其他作用的类,两者的不同是静态类不需要外部类去实例化就可以调用;后两个是定义在方法中的,也就是什么时候要用某个类就什么时候定义,只不过匿名类没有名字,本地类有名字(在程序中直接写一个类的定义,并在之后进行实例化)。在匿名类或本地类中使用主程序中的变量时,主程序变量需要使用final定义

六、数字和字符串

26.Java中跨系统的换行符“%n”

27.字符的一些方法:

Character.isLetter(c)     //是否为字母
Character.isDigit(c)       //是否为数字
Character.isWhitespace(c)    //是否为空白符
Character.isUpperCase(c)     // 是否为大写字母
Character.isLowerCase(c)      //是否为小写字母
Character.toUpperCase(c)     //转换为大写
Character.toLowerCase(c)      //转换为小写
Character.toString(c)         //转换为字符串

28.字符串的一些方法:

str.charAt(index)         //获取某个位置处的字符
str.toCharArray()         //转化为字符数组
str.subString(start, end=length)             //左闭右开截取字符串,end默认到最后
str.split(char)               //按某个字符分割字符串成字符串数组
str.trim()                      //删除首尾空格
str.indexOf(char or String) / str.lastIndexOf(char or String)             //字符串或字符在字符串str中第一次/最后一次出现的位置,没有返回-1
str.replaceAll("old", "new")/replaceFirst("old", "new")          //将字符串中的old子串替换成new子串
String类的equal()被重写了,比较的是两个字符串的内容是否相同,与"="效果不一样
str.startsWith(start) / str.endsWith(end)         //以...字符串开头或结尾

29.每当出现一个不一样的字符串字面值,就会在堆中用一个空间存放它,被当做一个对象看待。因此,当通过new String(“字面值”)的方式创建字符串,就会创建出两个对象,一个是字面值,一个是String类

30.StringBuffer类:
①该类与String类一样,内部维护一个字符数组,只不过String类在实例化的时候数组长度和字符串长度一样,但是StringBuffer类会分配更多的空间,所以有冗余的长度,看起来就像是变长一样。
②append(xxx) 、delete(start, end)、insert(start, xxx) 、reverse() 、length() 、capacity()
③在拼接字符串方面,StringBuffer的性能要比String好很多。原因是每次拼接的时候,对于String类每次都要在堆中创建新的对象,然后将地址引用给变量,而对于StringBuffer类都是在它的长度和内容上进行操作,不需要创建对象

七、日期

31.时间原点对应1970年1月1日8:00(UTC-8),通过new Date()创建的日期是当前日期,而new Date(xxx)创建距离时间原点xxx毫秒的日期。一般得到当前时间戳常用的是System.currentTimeMillis()函数,而非Date.getTime()

32.日历类Calendar能够方便地得到某一天的日期,而不需要复杂的逻辑运算

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值