9Java基础总结

1.psvm定义的意义

public:保证了方法的访问权限

static:保证在类未被实例化的时候就能调用(加载的时机)

void:不需要返回值

main:约定俗成的名字

String[] args:提供控制台传入的参数

2.代码块

代码块分为构造代码块和静态(类)代码块。

构造代码块随着对象的创建而执行,在每次实例化对象时执行,且加载时机优先于构造函数。可以在构造代码块中初始化成员变量和常量。(常量不赋初值会报错,JVM不会给他赋初值,但是可以在构造代码块中赋初值。)常量的声明可以放在构造代码块的后面。
在这里插入图片描述
在这里插入图片描述

静态代码块随类加载而加载,顺序上静态代码块优于构造代码块,优于构造函数。

在类方法/静态代码块中不能使用this,因为static先加载,不可能有对象存在,所以也不可能有对象调用方法。静态代码块中可以初始化静态变量和静态常量。常量的初始化可以放在静态构造块下面。
在这里插入图片描述
在这里插入图片描述

顺序练习:

在这里插入图片描述

在没有构造函数的情况下,静态变量是按照语句顺序执行赋值的。

在这里插入图片描述

在有构造函数的情况下,访问对象的静态变量,结果一定是构造函数中传入的值。因为构造函数的顺序在最后。

3.常用API

Math.random():返回【0.0,1.0)之间的浮点数。

System.currentTimeMillis():返回当前时间(距1970.01.01 0点的毫秒数)。经常用来计算一个方法的执行时间。

System.arraycopy(Object[] src,int srcPos,Object[] dest,int destPos,int length):从第一个数组的起始位置复制到第二个数组的起始位置,一共复制给定长度个元素。

Date date = new Date(); :返回当前时间的Date()对象。

date.getTime():返回毫秒数

SimpleDateFormat formatter = new SimpleDateFormat(格式);:创建一个格式器。

formatter.format(date);:格式化Date对象,返回一个格式化的字符串。

formatter.parse(dateString); :解析字符串,返回一个符合格式的Date。如果大于等于格式,就不会报错。如果小于格式,就会报ParseException。

Calendar.getInstance() :返回一个Calendar对象。

calendar.get(字段名);:返回日历对象对应的字段值。字段名是Calandar类中定义的常量,注意Calandar.MONTH返回的是0-11月份,Calandar.HOUR_OF_DAY返回的是24小时制。

BigDecimal():构造函数的参数可以是int,字符串,浮点数。BigDecimal可以对超过16位有效位的数进行精确运算。但是保存浮点数时还是非精确的,所以建议用字符串保存。

bigDecimal.加减乘除();:devide()如果除以0会报ArithmeticException。

4.包装类(八种基本数据类型的包装类)

常用方法:

构造函数(已弃用)
基本类型Value() :返回基本类型
两个数的最大值/最小值
parse基本类型:将字符串解析为基本类型,常用方法,如果含有不符合的符号会报NumberFormatException。
toString():
valueOf(基本类型/字符串):返回包装类型,和parse基本类型方法都是可以将字符串转换为基本类型的方法。

5.自动装箱和自动拆箱(java5之后出现)

自动装箱是指基本类型可以直接赋值为封装类型。JVM自动完成类型转换。自动装箱的过程实际是底层调用量valueOf()这个方法。

自动拆箱指封装类型可以直接赋值为基本类型。自动拆箱的过程实际是底层调用XXXValue()这个方法。

6.包装类的缓存问题

在这里插入图片描述

以Integer类为例,valueOf()方法返回的是包装类,而底层实现采用了缓存机制。如果这个简单类型在[-128,127]之间,就会使用IntegerCache的cache数组中的对象进行返回(缓存数组,在[0,255]的下标中存放了每个对象)。

而Float和Double类的valueOf()方法没有使用缓存,直接new 了对象。    Integer s = new Integer(9) ;//分配堆内存,地址。Java不推荐,推荐使用自动装箱的方法。

    Integer t = new Integer(9) ;//分配堆内存,地址。
    Long u = new Long(9) ;//分配堆内存,地址
   // System.out.println(s==u);//Operator '==' cannot be applied to 'java.lang.Integer', 'java.lang.Long'
    System.out.println(s==t);//false,两个不同地址的比较。
    System.out.println(s.equals(t));//true
    System.out.println(s.equals(9));//true
    System.out.println(s.equals(new Integer(9)));

    Integer a = 9;//相等于Integer a = Integer.valueOf(9);
    Integer b = 9;
    System.out.println(a==b);//true,两个都是cache数组的下标地址
    a= 128;
    b= 128;
    System.out.println(a==b);//false,超过了缓存范围,new的新对象
  Character c = 128;
    Character d = 128;
    System.out.println(c==d);//false,超过缓存范围
  Character e = -1;//注意char类的范围是0~2^16-1。

7.异常

异常是程序执行过程中出现的不正常情况。(开发中的语法错误和逻辑错误不属于异常。)

异常分为:

Error:JVM无法处理的严重问题。如内存错误,资源耗尽。
Exception:因为编程错误和偶然原因出现的一般性问题。一般使用try-catch块或throw、throws关键字处理。如果不处理异常,JVM会在控制台打印堆栈信息,并且程序会自动终止。
Exception分为:运行时异常和检查时异常。(只有RunTimeException子类,没有CheckedException子类)。

运行时异常是编译器不要求强制处理的异常,通常指编程错误。有常见的ArithmeticException、ClassCastException(not instanceof时)、IndexOutOfBoundsException、NullPointerException。

编译器异常是编译器要求处理的异常,即一般性异常,如果不处理则程序不允许运行。
在这里插入图片描述

8.try-catch-finally 和return顺序:

public class test {
    public int add(int a,int b) {
        try {
            return a+b;
        }catch(Exception e){
            System.out.println("catch语句块");
        }finally {
            System.out.println("finally语句块");
        }
        return 0;
    }
    public static void main(String[] args) {
        test t=new test();
        System.out.println("和是"+t.add(9, 34));//finally语句块,和是43
    }
 
}

当try块中有return语句,又有finally块时,会先把try块中的return 返回值保存到一个栈中。当finally块执行完时,再调出这个栈的内容返回。

![public class test {
    public int add(int a,int b) {
        try {
            return a+b;
        }catch(Exception e){
            System.out.println("catch语句块");
        }finally {
            System.out.println("finally语句块");
            a=1;
        }
        return 0;
    }
    public static void main(String\[\] args) {
        test t=new test();
        System.out.println("和是"+t.add(9, 34));//finally语句块 和是43
    }
 
}](https://img-blog.csdnimg.cn/d2128515056643b4b20a2528d457aa93.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0MjQyMzAz,size_16,color_FFFFFF,t_70)

在finally块中又对a进行赋值,但是并没有影响到栈中的内容,只改变了a的值,返回值没有变。

如果catch块中有return语句,finally块中没有return语句,情况也是类似的。

如果finally中也有return语句,最终会返回finally的返回语句。

try-catch块中,可以有多个catch块,但是只能进入一个catch块,并列catch块可以是同级类型,如果有父类异常应该放在最后。catch块捕捉的是异常对象。

9.throws/throw

throws抛出的是异常的类型,抛出异常可以是多个类型。

throws和throw的区别:

编写的位置:throw在方法体中,throws在方法声明上。
抛出的类型:throw抛出一个对象,throws抛出的是异常的类型。
抛出的个数:throw抛出一个对象,throws可以抛出多个类型。
在这里插入图片描述

10.自定义异常

自定义异常需要继承Exception类,在有异常的方法体中写throw 异常对象语句,并在这个方法的声明上标注throws 异常类型。(标注的地方是在参数列表后面)。

自定义异常需要重写无参构造和有参构造(String 异常信息)。

11.练习

在这里插入图片描述
在这里插入图片描述javac.exe:编译.java源文件为.class字节码文件

java.exe:解释器,通过java虚拟机来装载和执行编译文件(class文件)的。Java解释器是JVM的一部分。Java解释器用来解释执行Java编译器编译后的程序。java.exe可以简单看成是Java解释器。

javap.exe 类分析器 javap命令反汇编一个java字节代码文件, 返回有关可变部分和成员函数的信息

javadoc.exe 是java文档生成器
在这里插入图片描述
在这里插入图片描述
形参/局部变量不能用修饰符修饰的原因:java修饰符分为两种,访问控制修饰符和其他修饰符。

访问修饰符是用来供其他对象/方法调用时用的,但是局部变量只会有方法本身调用,已经设定了访问权限,所以不需要。

其他修饰符中,不能修饰变量的修饰符有abstract(方法和类)、synchronized(方法)。

对于static,被static修饰的东西的生命周期是和类一致,而局部变量的声明周期是和方法一致。

对于final,可以被final修饰,表示这个值是常量,只能被赋值一次。但是必须要赋初值,因为形参是不会被自动赋初值的。

(Java设定成员变量会被自动赋初值,因为成员变量的使用顺序是不确定的,可以在方法后被赋值并使用,但是局部变量的执行顺序是确定的(仅在方法体内),所以java为了避免程序员出错,必须给局部变量赋初值。)

(总结来说,成员变量在程序中从来没有手动赋值,程序不会出错,而final常量和局部变量从来没有手动赋值,语法就会报错,常量可以在方法块、构造函数这些类加载时能运行到的地方赋值,局部变量可以在访问变量前赋值)
在这里插入图片描述对于transient,是用来在序列化中修饰不需要被序列化的变量,使其不持久化。transient不能用来修饰局部变量,因为它不是成员变量。

对于volatile,是用来在多线程中保证变量的值是最新的值。局部变量不存在可见性问题。
在这里插入图片描述
对于形参是引用变量类型,我们首先知道虽然形参不能改变实参,但是通过可以修改地址中的对象。形参列表中三个变量都是引用类型。

对于String s,操作是s = s+“t”。对于变量和常量的拼接,返回的是StringBuilder.append()后,new String()的地址,所以改变了形参的值,没有改变原来的对象(字符串对象是不可变的)。因此实参s没有发生改变。

对于StringBuffer s1,操作是s1.append(“1”)。StringBuffer对象是可变的,所以修改的是s1对象。实参s1发生了改变。

对于StringBuffer s2,操作时s2= new StringBuffer(“C1”);。没有改变s2对象的值,修改的是形参的地址。所以实参s2没有改变。
在这里插入图片描述
在这里插入图片描述
违反了局部变量不能被生命周期为类的static修饰的道理。
在这里插入图片描述
在这里插入图片描述
类的初始化顺序:

  1. 父类静态代码块

  2. 子类静态代码块

  3. 父类普通代码块

  4. 父类构造函数

  5. 子类普通代码块

6. 子类构造函数
在这里插入图片描述
在这里插入图片描述
Parent x =new Child();是多态中向上转型的体现,此时x.i是Parent的变量,x可以调用f()。x.f()是Child的方法,但是方法调用中用到的变量i,首先会查找方法的局部变量,然后是Child的成员变量,最后是Parent的成员变量。因此x.i=20,x.f()显示30。Child x1 = (Child)x,是向下转型的体现。x1可以调用f()和g()。编译期就会确定x1的类型是Child,所以x1.i=30,x1.f()也是就近原则,显示30。所以最终结果是20 30 20 20。

如果改为Parent x1 = (Child)x;尽管此时也完成了向下转型,但是又向上转为Parent。此时x1没有g()方法,最后结果是20 30 20 30。
在这里插入图片描述
在这里插入图片描述
类方法中不可以使用this,因为类方法加载的时期中没有对象存在;类方法中可以调用本类和其他类的类方法;类方法中可以创建对象,并调用这个的对象的实例方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值