Java基础(一):编译和解释、数据类型、变量作用域、String常用方法、数组、面向对象、异常

导读:本篇文章讲解 Java基础(一):编译和解释、数据类型、变量作用域、String常用方法、数组、面向对象、异常,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

Java基础(一):编译和解释、数据类型、变量作用域、String常用方法、数组、面向对象、异常

Java基础(二):集合、IO流(Zip压缩输入/输出流等)、File文件类、反射、枚举

Java异常、继承结构、处理异常、自定义异常、SpringBoot中全局捕获处理异常

Java–JUC之CountDownLatch、Semaphore以及CyclicBarrier

Java多线程基本概念、线程的创建方式(有、无返回值)、常用方法、synchronized锁、线程安全问题、死锁以及如何避免

Java基础(一)

编译和解释

Java语言编写的程序既是编译型的,又是解释型的。源码编译之后成为字节码文件,JVM可以对字节码文件进行解释和运行。编译只需要执行一次,解释是在每次程序运行时都会进行。JVM虚拟机将.class(字节码文件)解释为机器码,然后在计算机上运行(CPU执行只能读懂二进制的机器码)。

在这里插入图片描述

版本

  • Java SE:标准版,包含java基础,JDBC,IO,网络通信,多线程等,主要用于桌面应用开发
  • Java EE:企业版,应用于企业级分布式的网络程序,核心是EJB(企业Java组件模型,后面使用spring的javaBean容器代替了EJB)
  • Java ME:主要应用于嵌入式系统开发,掌上电脑,手机等移动通信电子设备。

数据类型

整型

整数类型为 byte,short、int、long 4种类型,有各自的取值范围,若定义时超过了各自的取值范围,那么会报错的。对于long类型,若赋的值大于 int类型的最大值或小于int类型的最小值,那么需要在后面加 L或者l,表示该数值为long类型。

浮点数

浮点数有单精度浮点数(float)和双精度浮点数(double),取值范围不相同。

牢记:默认情况下小数都是被看做是double类型的,若要使用float型小数,那么需要在数值的后面加上 F或者f。也可以使用后缀Dd来表示是一个double类型,当然不加也可以,因为是默认的。

字符类型

  • char型,用于存储单个字符,空间占位16位(2个字节),值只能是单个字符。如char x ='a';其中字符a在unicode(码表)表中排位97,所以可以写成char x = 97;。java中也可以将字符当做整数来对待,unicode码表中存储着65536个字符,可以通过字符排序位置来获取到相应的字符,如

    int a = 44332;
    // 直接获取在unicode码表中位置是44332的字符
    System.out.println((char) a);
    
  • 转义字符

    转义字符是以\开头,后面跟一个或多个字符。如换行\n、一个垂直制表符\t,反斜杠字符\\

布尔类型

通过关键字boolean定义变量,只有true和false两个值,默认值是false。

常量

常量是指被final修饰的变量,常量只能被赋值一次,且必须在声明时就赋值,否则编译不过。而且,对于基本数据类型来讲final修饰的变量,值是不能改变的,而对于引用数据类型来讲,只有引用不能变,假如要修改对象内部的属性还是可以做到的。常量的名称尽量大写。

变量作用域(有效范围)

变量的作用域分为成员变量局部变量

成员变量

成员变量被定义在类中、方法外部,分为类变量(static修饰)和实例变量。类变量是属于整个Class类的,调用者可以通过类名.变量名方式调用,而实例变量是属于某个实例的,也就是每个实例都会有自己的实例变量,互不干扰。

局部变量

定义在类中、方法内部,包括方法参数都是局部变量,局部变量只作用域当前方法内部,外部无法访问。且生命周期仅在方法执行期间,方法执行完毕后,这些局部变量都会被回收。

成员变量和局部变量的区别

  • 定义位置不同,成员变量定义于类中方法外,局部变量定义于类中方法内
  • 生命周期不同,成员变量中类变量是伴随着Class类信息被加载进JVM时就一直存在直到程序结束;实例变量是伴随着对象的产生和死亡;局部变量是随着方法的执行和执行完毕
  • 初始化机制不同,成员变量可以没有初始值,那么会被赋予默认值,但是局部变量在使用前必须赋值,否则编译报错
  • 作用域不同,成员变量是全局性的,局部变量是局部的(只在方法内部被访问)

逻辑运算符

  • &、&&: &是逻辑与,&&是短路与,区别:&条件中的表达式都会被执行,&&条件中的表达式如果前者返回值为false,那么后面的条件表达式不再执行
  • |、||: |是逻辑或,||是短路或,区别:|条件中的表达式都会被执行,||条件中的表达式如果前者返回值true,那么后面的条件表达式不再执行
  • ! : 取反

String常用方法

  • length()

  • indexOf()、lastIndexOf()

  • charAt()获取指定索引位置的字符

  • subString()

  • trim()

  • replace()、replaceAll()

  • contains()是否包含字符串

  • startsWith()是否以..字符串开头、endsWith()是否以...字符串结尾

  • equals()、equalsIngnoreCase()忽略大小写比较字符串

  • split()分割字符串,以...字符串进行分割

  • format(),格式化字符串,是一个静态方法

StringBuffer和StringBuilder

过多操作字符串时,尽量采用StringBuffer或StringBuilder类来进行操作,因为如果使用String,每次字符串拼接时使用+可以达到目的,但是产生一个新的String的实例,会在内存中创建字符串对象。

多线程时采用StringBuffer安全性高,单线程使用StringBuilder效率高

数组

基础

数组是引用数据类型,在堆内存中开辟一块空间。定义方式有两种,一种是动态的,一种是静态的。动态是指声明完数组后,动态使用下标赋值数据,静态是声明时就将数据给定义好

// 动态写法
int[] a = new int[3];
a[0] = 1;
a[1] = 2;
a[2] = 3;

// 静态写法
int[] b = new int[]{1,2,3};

要注意:如果是基本数据类型的数组,默认值都是该基本数据类型的默认值,如果是引用数据类型的数组,那么数组中元素的默认值都是 null

  • Arrays.fill(),填充替换数组中的元素(可指定下标范围或全部),会将数组中的值给替换掉。
  • Arrays.sort(),数组排序,基本数据类型就是按照值进行排序,引用类型按照算法实现(一般就是实现了Comparable,重写compareTo方法定义排序规则)
  • Arrays.copyOf(),Arrays.copyOfRange(),复制全部/下标范围的数组
  • Arrays.binarySearch(),二分查询法查询元素在数组中的位置

排序:冒泡排序

public class BubbleSortTest {

    public static void main(String[] args) {
        int[] arr = new int[]{24, 32, 65, 2, 13};
        BubbleSort.sort(arr);
    }
}

class BubbleSort {

    static void sort(int[] arr) {
        
       // 控制轮数(数组数量-1次)
        for (int i = 1; i < arr.length; i++) {
            // 控制比较的次数,每一轮比较的次数逐渐减少的,因为最末尾的数一个个被确定好了
            for (int j = 0; j < arr.length - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }

        }
        System.out.println(Arrays.toString(arr));
    }
}

排序:直接选择排序

与冒泡排序不同,直接选择排序是从待排序的数组中直接找出最大或最小值进行排序。

public class SelectSortTest {
    public static void main(String[] args) {
        int[] arr = new int[]{32, 45, 13, 44, 26};
        SelectSort.sort(arr);
    }
}

class SelectSort {
    
    static void sort(int[] arr) {
        // 外层控制轮数(数组数量-1)
        for (int i = 1; i < arr.length; i++) {
            int index = 0;
            // 内层控制比较次数,每次比较的次数都会递减,因为最大值已经被确认好了
            for (int j = 1; j <= arr.length - i; j++) {
                if (arr[j] > arr[index]) {
                    index = j;
                }
            }
            // 每一轮找出最大值的 索引,然后直接替换
            int temp = arr[arr.length - i];
            arr[arr.length - i] = arr[index];
            arr[index] = temp;
        }
        System.out.println(Arrays.toString(arr));
    }
    
}

排序:反转排序

就是将数组中的所有元素反转过来。思想比较简单:思路就是把数组中最后一个元素和第一个元素位置替换,假如数组中个数是奇数,那么有一个元素就不需要进行替换.

public class ReverseTest {

    public static void main(String[] args) {
        int[] arr = new int[]{10, 20, 30, 40, 50};
        Reverse.sort(arr);
    }

}

class Reverse {

    static void sort(int[] arr) {
		// 替换 数组的二分之一次
        for (int i = 0; i < arr.length / 2; i++) {
            int temp = arr[i];
            arr[i] = arr[arr.length - 1 - i];
            arr[arr.length - 1 - i] = temp;
        }
        System.out.println(Arrays.toString(arr));
    }

}

面向对象

三大特性

  • 封装
  • 继承
  • 多态

权限修饰符

修饰符 本类 同包 子类 其他包
public
protected ×
friendly(default) × ×
private × × ×

对象的比较

  • ==:直接比较引用地址是否相同
  • equals:一般对象可重写equals方法自定义比较规则,默认是Object的equals方法,就是比较地址

对象的销毁

每个对象都有生命周期,当对象的生命周期结束时,分配给该对象的内存地址将会被回收,Java中会自动进行垃圾回收,什么样的对象会被视为垃圾呢?

  • 对象引用超过其作用范围时(感觉可以理解为在方法内部定义的,并且使用完了)
  • 对象的引用设置为null

gc(垃圾回收)只能回收由new创建的对象,如果某些对象不是通过new创建并在内存中获取的内存,这种对象可能无法被gc机制识别;Object类中提供了一个finalize()方法,开发者可以重写这个方法,垃圾回收时会先调用对象的finalize(),并且下一次垃圾回收时,真正回收对象占用的内存。

包装类

包装类是对byte、int、boolean等基本数据的包装,包装类是引用数据类型,默认值是null。包装类提供了更多操作数据的方法

基本数据类型和包装类之间的转换被称为装拆箱

  • 装箱:基本数据类型—>包装类
  • 拆箱:包装类—>基本数据类型

常用方法:

  • xxxValue:转为指定的基本数据类型,如intValue()…

  • xxx.valueOf():将字符串转为指定的基本数据类型,如Integer.valueOf(“”);

  • String.valueOf():将指定的数据转为String类型

涉及到数学计算的尽量使用BigDecimal类,并且避免使用new BigDecimal(0.1)的方式,尽量使用BigDecimal.valueOf("0.1")的方式。

Math数学工具类

Math工具类提供了基于数学运算的方法和一些常用的数学常量,如PI、E等。

常用方法:

  • 一些三角函数的方法:sign(),cos(),tan()…
  • 指数函数:exp()、log()…
  • 取整函数:ceil()、floor()、round()…
  • 最大、最小值、绝对值:max()、min()、abs()
  • Math.random()随机数:生成0~1之间的一个double类型的数据

抽象类和接口

相同点:

  • 抽象类和接口都是不能实例化
  • 由子类继承/实现,重写抽象方法

不同点:

  • 抽象类中可以定义普通方法,接口中只能定义抽象方法,和一些default、static修饰的方法
  • 抽象类是被单继承,接口可以被多实现
  • 抽象类中可以定义普通变量,接口中定义的都是静态常量

题:如果C类想要有A类和B类中的特性,那么需要A、B类产生父子关系,然后C类继承自即可。

final的作用

  • final修饰变量,表示是常量
  • final修饰方法,表示方法不能被重写
  • final修饰类,表示此类是不可变类,且无法被继承。

异常

基础

首先异常类的父类Throwable类,子类有ErrorException,其中Error为系统级别的错误,为不可控的错误,无法通过调优方式缓解,多为代码问题需要优化。Exception中的子类RuntimeException和其他异常类,RuntimeException是指在程序运行期间出现的问题,指的是非受查异常,编译器不会进行检查这种异常,需要开发者自行检测和处理(捕获异常处理,或抛出异常交给调用者处理);其他类异常指的就是受查异常,编译器会进行检查这种异常,并且强制开发者处理或抛出此异常。

需要注意的一点:程序运行中出现了异常,但是没有进行捕获处理时,程序将会停止运行!!!,所以一般在SpringBoot中都会有全局异常处理。

系统级别的错误:

  • OOM等

受查异常:

  • IOException
  • SQLException

非受查异常:

  • RuntimeException子类:数组越界、空指针、非法参数…

处理异常

处理异常可以使用: try-catch、try-catch-finally进行捕获异常,捕获到异常后可以选择继续抛出异常或者处理,但是千万不要把异常给偷偷吃掉,否则后期调试就是调试地狱。

简单捕获处理。

public static void main(String[] args) {
    try {
        int i = 5 / 0;
        System.out.println(i);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        System.out.println("执行完毕了");
    }
}

其中要注意finally

  • 假如方法中有返回值,而在finally中写了return语句,不出意外的情况下一定是走的finally的return
  • 方法中有返回值,finally中没写return,但是有修改要return的变量,如果是基本数据类型,在finally中修改要return的变量是无用的,而如果是引用数据类型,finally中修改对象的某个属性值却是完全没问题的。

什么情况下finally不会执行?

  • finally语句块中出现了异常
  • System.exit()手动退出程序了
  • 程序所在的线程死亡
  • CPU关闭了

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/48377.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!