万字Java基础原理知识大总结(下)

简介: Java诞生于1995年,原属于SUN公司,2009年4月20日,美国数据软件巨头甲骨文公司(Oracle)宣布以74亿美元收购SUN公司。Java是最受欢迎的开发语言,已经火了20年,并将继续引领着IT的编程语言。Java的LOGO是一杯热气腾腾的咖啡,真的是令人回味无穷。

九、数组


9.1、JVM初探究


3.JPG


  • 程序计数器:当前线程所执行的字节码的行号的指示器
  • 本地方法栈:为虚拟机使用的native方法服务
  • 方法区:线程共享的内存区域,存储已经被虚拟机加载的类的信息、常量、静态变量,这个区域的内存回收的目标主要是针对常量池的回收和对类型的卸载
  • Java虚拟机栈:简称栈,每个方法被执行的同时会创建一个栈帧用于存储该方法的局部变量、操作栈、动态链接、方法出口等信息
  • Java堆:被所有线程共享的一块内存区域,在虚拟机创建的时候启动,所有对象的实例(new出来的对象)以及数组都要在堆上分配内存空间,所以堆占的内存空间远比栈大
  • 每当调用一个方法时,创建一个栈帧,存放了当前方法的局部变量,当方法调用完毕时,该方法的栈帧就被销毁了
  • 每次new一个对象的时候,就表示在内存中开辟了一块新的存储空间


9.2、数组


9.2.1、什么是数组


具有相同类型多个常量值有序组织起来的一种数据形式,数组中使用索引来表示元素存放的位置,索引从0开始步长是1,有点像Excel表格的行号


4.JPG


9.2.2、定义语法


数组元素类型[]  数组名;
int [] nums;
复制代码


注意:

  1. 可以把int[] 看成一种数据类型,int类型的数组类型
  2. int[]数组表示,这个数组中的元素都是int类型的,同理


9.2.3、数组的初始化


数组在定义后,必须初始化才能使用。所谓初始化,就是在堆内存中给数组分配存储空间,并为每一个 元素赋上初始值,有两种方式:静态初始化和动态初始化数组的长度是固定的,无论以哪种,一旦初始化完成,数组的长度(元素的个数)就固定了,不能改变,除非重新对该初始化,初始化时,如果我们明确了具体的元素就用静态初始化,如果还不知道具体放哪些元素,只知道个数,用动态初始化


9.2.3.1、静态初始化


我们直接为每一个数组元素设置初始化值,而数组的长度由系统(JVM)决定

语法:数组元素类型[] 数组名 = new 数组元素类型[]{元素1,元素2,元素3,.......};


int[] nums = new  int[]{1,3,5,7,9};
//简单写法:
int[] nums = {1,3,5,7,9};//简单写法,定义和初始化必须同时写出来
复制代码


9.2.3.2、静态初始化内存分析


public class ArrayDemo1{
  public static void main(String[] args) {
//定义并初始化数组
    int[] nums = new int[] { 1, 3, 5, 7 };
    System.out.println("数组长度=" + nums.length);
//重新初始化数组
    nums = new int[] { 2, 4, 8 };
    System.out.println("数组长度=" + nums.length);
  }
}
复制代码


5.JPG


若 num = null,则null表示不再引用堆中的内存空间,那么此时nums就好比是没有初始化的,不能使用


9.2.3.4、动态初始化


程序员只设置数组元素个数,而数组的元素的初始值由系统(JVM)决定

语法:数组元素类型[] 数组名 = new 数组元素类型[length]; int[] nums = new int[5];

注意:不能同时指定元素值和数组长度,int[] nums = new int[5]{1,3,5,7,9} 是错误的


内存图与静态初始化一样,只是拥有默认值


9.2.4、数组中对元素的操作


9.2.4.1、获取元素的个数


int size = 数组名.length;


9.2.4.2、设置元素


nums[1] = 30;


9.2.4.3、获取元素


元素类型 变量名 = 数组名[index];


9.2.5、数组中常见的异常


  1. NullPointerException:空指针异常(空引用异常)

操作了一个尚未初始化或者没有分配内存空间的数组

  1. ArrayIndexOutOfBoundsException:数组的索引越界异常

操作的数组的索引不在[0,数组名.length-1]范围内


9.2.6、数组遍历


9.2.6.1、for循环


int[] nums = new int[] { 1, 3, 5, 7 };
for (int index = 0; index < nums.length; index++) {
    int ele = nums[index];//index依次是 0、1、2、3
    System.out.println(ele);
    }
复制代码


9.2.6.2、for-each(增强for循环)


for(数组元素类型 变量: 数组){
//TODO
}
复制代码
int[] nums = new int[] { 1, 3, 5, 7 };
for (int ele : nums) {
System.out.println(ele);
}
复制代码


使用for-each操作数组更简单,因为可以不关心索引,其底层原理依然是上述的for循环操作数组


9.2.7、二维数组


在之前,数组的每一个元素就是一个个的值,这种数组我们称之为一维数组。二维数组,就是数组中的每一个元素是另一个一维数组


9.2.7.1、二维数组的定义和初始化


静态

public class ArrayInArrayDemo1 {
public static void main(String[] args) {
//定义三个一维数组
int[] arr1 = { 1, 2, 3 };
int[] arr2 = { 4, 5 };
int[] arr3 = { 6 };
//把三个一维数组存储到另一个数组中,那么该数组就是二维数组
int[][] arr = new int[][] { arr1, arr2, arr3 };
}
}
复制代码


二维数组中的元素类型是一维数组,把数组元素类型[]看成一个整体,表示数据类型


动态

数组元素类型[][] 数组名 = new 数组元素类型[x][y];
x表示二维数组中有几个一维数组
y表示每一个一维数组中有几个元素。
int[][] arr = new int[3][5];
复制代码


9.2.7.2、获取二维数组的元素


for循环

for (int index = 0; index < arr.length; index++) {
//取出每一个一维数组
int[] arr2= arr[index];
//迭代一维数组
for (int j = 0; j < arr2.length; j++) {
int ele = arr2[j];
System.out.println(ele);
}
System.out.println("-----");
}
复制代码

for-each

for (int[] arr2 : arr) {
  //arr2为每次遍历出来的一维数组
for (int ele : arr2) {
    //ele为从arr2一维数组中遍历出来的元素
System.out.println(ele);
}
System.out.println("-----");
}
复制代码


十、方法


10.1、方法的定义


方法:为了完成某一特定功能(如:求和,统计数量等)的代码块

语法格式:


修饰符] 返回值类型 方法名称(参数类型 参数名1,参数类型 参数名2,…)
{
方法体;
[return 返回值;]
}
复制代码


格式分析:

  • 修饰符:public、static等,static修饰的方法直接使用类名调用即可,用static修饰的方法都属于类的
  • 返回值类型:限定返回值的类型,方法在完成一个功能后,是否需要给调用者返回一个结果?
  1. 如果需要给调用者返回结果,就写上返回数据的类型
  2. 如果不需要给调用者返回结果,就用关键字void,表示没有返回结果
  • 方法名称:用于调用方法,遵循标识符规范,首字母小写,采用驼峰命名法,见名知意
  • 形式参数:方法中圆括号中的变量,可以有多个形式参数
  • 方法体:编写如何完成该功能的代码
  • return关键字的作用
  1. 把返回值给方法的调用者
  2. 结束该方法,在return后不可以再学任何语句
  3. 当方法体中没有return时,方法的返回值类型必须为void
  • 实际参数:在调用某一个具体方法1时,实际传递的参数值
  • 如果一个需要返回值,那么一定要保证在任何条件下都必须得有返回值


注意事项

  1. 方法必须定义到类中,在java中最小的程序单元是类
  2. 一个类中可以定义多个方法
  3. 方法和方法之间是平行的,不能在一个方法中定义另一个方法(相当于不可以在一个房子里面建房子)
  4. 方法定义没有先后顺序


10.2、方法的调用


如果方法有static修饰,可以直接用方法所在的类的类名调用,如果没有static修饰,那么必须使用实例化对象来调用


10.3、方法的重载


参数列表:参数的类型+参数的个数+参数的顺序

方法签名:方法名称+方法的参数列表

在同一个类中,方法签名是唯一的,否则编译报错

方法的重载:在同一个类中,允许某方法存在一个或者多个同名的方法,但是必须参数列表不同


10.3.1、如何是否是方法重载


方法重载判断的原则:两同一不同

两同:在同一个类中方法名相同

一不同:方法的参数列表不同(参数类型、参数个数、参数顺序),只要参数类型、参数个数、参数顺序其中有一个不同,都成为参数列表不同

方法的重载和返回值类型无关,只是一般都要求返回值类型相同


10.3.2、方法重载的作用


解决了同一功能的方法由于参数不同所造成的方法名称不同而需要重复命名的问题



相关文章
|
1月前
|
存储 Java 关系型数据库
高效连接之道:Java连接池原理与最佳实践
在Java开发中,数据库连接是应用与数据交互的关键环节。频繁创建和关闭连接会消耗大量资源,导致性能瓶颈。为此,Java连接池技术通过复用连接,实现高效、稳定的数据库连接管理。本文通过案例分析,深入探讨Java连接池的原理与最佳实践,包括连接池的基本操作、配置和使用方法,以及在电商应用中的具体应用示例。
76 5
|
2月前
|
存储 算法 Java
Java HashSet:底层工作原理与实现机制
本文介绍了Java中HashSet的工作原理,包括其基于HashMap实现的底层机制。通过示例代码展示了HashSet如何添加元素,并解析了add方法的具体过程,包括计算hash值、处理碰撞及扩容机制。
|
6天前
|
监控 Java API
探索Java NIO:究竟在哪些领域能大显身手?揭秘原理、应用场景与官方示例代码
Java NIO(New IO)自Java SE 1.4引入,提供比传统IO更高效、灵活的操作,支持非阻塞IO和选择器特性,适用于高并发、高吞吐量场景。NIO的核心概念包括通道(Channel)、缓冲区(Buffer)和选择器(Selector),能实现多路复用和异步操作。其应用场景涵盖网络通信、文件操作、进程间通信及数据库操作等。NIO的优势在于提高并发性和性能,简化编程;但学习成本较高,且与传统IO存在不兼容性。尽管如此,NIO在构建高性能框架如Netty、Mina和Jetty中仍广泛应用。
21 3
|
6天前
|
安全 算法 Java
Java CAS原理和应用场景大揭秘:你掌握了吗?
CAS(Compare and Swap)是一种乐观锁机制,通过硬件指令实现原子操作,确保多线程环境下对共享变量的安全访问。它避免了传统互斥锁的性能开销和线程阻塞问题。CAS操作包含三个步骤:获取期望值、比较当前值与期望值是否相等、若相等则更新为新值。CAS广泛应用于高并发场景,如数据库事务、分布式锁、无锁数据结构等,但需注意ABA问题。Java中常用`java.util.concurrent.atomic`包下的类支持CAS操作。
30 2
|
1月前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
1月前
|
Java
Java之CountDownLatch原理浅析
本文介绍了Java并发工具类`CountDownLatch`的使用方法、原理及其与`Thread.join()`的区别。`CountDownLatch`通过构造函数接收一个整数参数作为计数器,调用`countDown`方法减少计数,`await`方法会阻塞当前线程,直到计数为零。文章还详细解析了其内部机制,包括初始化、`countDown`和`await`方法的工作原理,并给出了一个游戏加载场景的示例代码。
Java之CountDownLatch原理浅析
|
1月前
|
Java 索引 容器
Java ArrayList扩容的原理
Java 的 `ArrayList` 是基于数组实现的动态集合。初始时,`ArrayList` 底层创建一个空数组 `elementData`,并设置 `size` 为 0。当首次添加元素时,会调用 `grow` 方法将数组扩容至默认容量 10。之后每次添加元素时,如果当前数组已满,则会再次调用 `grow` 方法进行扩容。扩容规则为:首次扩容至 10,后续扩容至原数组长度的 1.5 倍或根据实际需求扩容。例如,当需要一次性添加 100 个元素时,会直接扩容至 110 而不是 15。
Java ArrayList扩容的原理
|
2月前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
92 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
1月前
|
存储 Java 关系型数据库
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践,包括连接创建、分配、复用和释放等操作,并通过电商应用实例展示了如何选择合适的连接池库(如HikariCP)和配置参数,实现高效、稳定的数据库连接管理。
69 2
|
1月前
|
Java 数据格式 索引
使用 Java 字节码工具检查类文件完整性的原理是什么
Java字节码工具通过解析和分析类文件的字节码,检查其结构和内容是否符合Java虚拟机规范,确保类文件的完整性和合法性,防止恶意代码或损坏的类文件影响程序运行。
51 5