2021-05-18


异常类型:
InputMisMatch Exception----输入类型不匹配
Array Index OutOf Bounds Exception----数组索引越界
NegativeArraySizeException----运行时的异常,创建数组的时候长度给了负数,数组的长度不合法

基本概念

JVM:

JVM Java Virtual Machine虚拟机
JVM会在内存中开辟一块空间,从而将源文件编译成字节码文件
##计算机硬件组成:
内存(条形的芯片 临时执行使用的)、硬盘(矩形的 有机械硬盘和固态硬盘 永久性保存的)
应用在系统之上的软件=应用软件
硬盘上的文件有不同的格式,所以有不同的后缀名(.txt .doc .ppt .xls等),需要不同的运行环境的支持
源文件.java 字节码文件.class

JRE:

Java Runtime Environment 运行环境
可以运行别人写好的程序
##JDK:

  • Java Development Kit 开发工具包,这些开发工具包全部存储于bin目录,有两个很重要的工具:javac.exe(编译工具,编译形成字节码文件)和java.exe(执行工具,形成字节码文件后用这个工具执行),这些工具只能在底层的doc窗口才能看到效果
  • 开发时需要用到的工具,为了开发后能够运行,所以:JDK包含JRE,JRE包含JVM
  • include文件夹包含了其他语言写的程序
  • jre文件夹包含运行环境
  • lib文件夹包含人家写好的所有的java类,以.jar形式存在
  • release包含配置文件
  • src.zip压缩文件存储源代码

搭建环境(安装JDK)

在官方网站下载JDK安装程序,这是Oracle公司的产品,所以去www.oracle.com下载
卸载的话去控制面板卸载

===============================

写一个基本的java源代码:

1.首先新建一个记事本,将后缀改为.java,然后以记事本形式打开该源文件
2.先写一个关键字class---->表示类的意思
3.类后面起一个名字---->理论上可以随便写,但是有规则和规约

命名规则和规约

规则 名字中可以含有如下信息:

字母(区分大小写,52个英文字母可以用)
数字(0-9可以用,但不可以用做开头)
符号(英文符号 仅两个: _ $)
中文(强烈不推荐---->当做不行)
规约:
类的名字 需要首字母写,例如TestOne,如果两个以上的单词,则每个单词的首字母都要大写
变量的名字 需要首字母写,例如testOne,如果两个以上的单词,则除了第一个单词之后的每个单词的首字母都要大写,遵循驼峰式命名规约
起名字的时候要见名知义,尽量使用英文单词,增强程序可读性
4.类名后边组大括号,表示当前类的内容

利用JDK包提供的工具,进行代码的编译及执行:

  • 由于源代码.java的所在路径和编译工具javacexe并不在一起,而且编译工具直接双击的话是一个黑色对话框一闪而过,编译工具在doc命令窗口才可以使用---->window键+R打开运行窗口,输入cmd指令打开doc命令行窗口
  • 刚打开doc窗口,默认在C盘,切换到盛放编译工具的盘,我放在了D盘/java/jdk/bin/下:
1、d:(cd..是退出一层文件夹)
2、cd java
3、cd jdk*(表示切换到所有jdk开头的文件夹,此时打开的是jdks文件夹)  
4、cd jdk*(这时打开的是jdk1.8.0_281文件夹)
5、cd bin
6、javac(表示直接运行这个工具),可以看到好多信息

配置环境变量:

  • 我的电脑(右击)—属性—高级系统设置—环境变量—用户变量(上半部分)—变量名Path—双击或者编辑—将安装工具的目录放到里边去(D:\Java\jdks\jdk1.8.0_281\bin),点击新建,复制进去—如果要将这个放到第一个,选中点击上移即可—确定—确定—确定

配置path是为了让工具在任何位置都可以用
classPath 作用是不管源文件在哪,生成的class文件都统一存储在配置的目录下(就是生成的字节码文件的存储位置)
JAVA_HOME 目的是为了让路径的写法变得简单(相对路径的写法)
例如:JAVA_HOME C://program files/java/jdk
path %JAVA_HOME%/bin

利用javac工具编译:

doc窗口:

e:(切换到e盘,因为我把test测试代码放到了e:\javatest)
cd e:
cd test
javac Test.java(javac编译Test.java文件)
  • 若我的Test1.java里的代码编写正确的话,javac编译了Test1.java文件后,文件夹就会多一个类名.class文件,此时我命名的类名为Demo
  • 编译完成后,使用java.exe工具来运行:
java Demo(注意:运行的时候不需要写后缀.class)

结果提示运行错误:

错误: 在类 Demo 中找不到 main 方法, 请将 main 方法定义为:
   public static void main(String[] args)
否则 JavaFX 应用程序类必须扩展javafx.application.Application

这是因为我编写的Test1.java文件里没有主方法,主方法是程序入口

class Demo{
	public static void main(String[] args){
	
	}
}

public:叫做访问权限修饰符,表示共有的
static:特征修饰符,有且只有一份
void:表示当前程序访问完没有返回结果
main:必须叫main,方法名
String[] args:参数列表
String:字符串
[]:数组
args:变量名(arguments)
这个主方法里{}写的是主方法的执行过程,这一堆除了args这个变量名可以改都是固定的

  • 由于修改了Test1.java,所以重新编译,再执行:
C:\test>javac Test1.java

C:\test>java Demo

什么效果也没有,是因为他执行了一个方法,但是方法里什么都没有做,所以再编写方法:

class Demo{
	public static void main(String[] args){
		System.out.println("fgsdas");
	}
}

方法里写的表示输出fgsdas,print后加ln是换行的意思:

C:\test>javac Test1.java

C:\test>java Demo
fgsdas

C:\test>

这个FGSDAS后的空行就是ln发挥的作用
这就是基本的java代码的编写了
但是这样的话,会有一个问题,就是生成文件和字节码文件的名字不一致,如果文件数目多的话会记不住,所以这样改进:
在class前边加一个public,但是加了public之后运行会出错误,这是因为加了public后,要求当前类的名字要与字节码文件的名字一致:

public class Test{
	public static void main(String[] args){
		System.out.println("fgsdas");
	}
}

以上是一个标准类的写法!!

===============================

标题数据类型

  • 基本数据类型有8个
    4个整型:

按照存储的单位大小由小到大:
byte(字节型)、short(短整型)、int(整型)、long(长整型64位)

2个浮点型:

从精确长度由小到大:
float(单精度32)、double(双精度64)

1个字符型:

char

1个布尔型:

boolean

  • 引用数据类型
    数组[]
    类class(抽象类abstract class)
    接口interface
    枚举enum
    注解@interface

基本数据类型;

整型:

byte 字节型 1字节

1byte== 8bit(敏感单元位) 0 0000000 256种组合
第一个bit位置记录符号:0表正数、1表负数
所以数值的范围是 -2的7次方 ~ 2的7次方-1(因为0放到了正的那边)即-128~127

short 2字节 == 16bit 65526种组合

所以数值的范围是 -2的15次方 ~ 2的15次方-1(因为0放到了正的那边)即-32768~32767

int 4字节 == 32bit

所以数值的范围是 -2的31次方 ~ 2的31次方-1(因为0放到了正的那边)即-2147483648~2147483647

long 8字节==64bit

所以数值的范围是 -2的63次方 ~ 2的63次方-1(因为0放到了正的那边)

浮点型:

float 32bit 4字节

0 000000000 00000000000000000000
第一位表示符号,然后九位表示整数部分,剩下的表示小数部分

double 64bit 8字节

第一位表示符号,然后十九位表示整数部分,剩下的表示小数部分

字符型:

char 16bit 2字节 中文是Unicode编码 范围是0-65535

中文两个字节,英文、符号、数字一个字节
键盘能输出来的都算字符型,但是字符中数字和整数的数字冲突,为了区分,所以每个字符的前后各加单引号

布尔型:

boolean 1bit 1/8字节

true、false

===============================================

java常量与变量

常量

代表程序在运行过程中不能再次改变的值

常量作用:

  • 固定的值 计算过程中经常用到的值,便于程序计算,比如圆周率pi
  • 代表一个含义
    这样的值可以算作常量:
  • 固定不变的值,比如:1 3.14 ‘a’ true
    可以认为所有基本类型的值固定不变
  • 特殊的常量
    例如:“abc”—>String类型,这是一个引用数据类型,值很特殊,可以简单的视为常量
  • 自己创建的空间,存储一个值,让它固定起来,比如:
    final int up = 1;用final修饰的这个空间的值是不能改变的

常量的存储形式是以二进制形式存储的:

  • 如果是整数,比如1---->以32位bit位形式存储(相当于int型)
  • 如果是小数,比如3.4---->以64位bit位形式存储(相当于double型)
    ##变量
    指程序执行过程中可以改变的
    变量是一个内存空间(小容器),变量空间在创建(声明)的时候必须要指定数据类型和变量空间的名字,且变量空间只能存储一个内容(值、引用),变量空间的内容可以改变
    创建变量时需要注意命名问题,上边有记录命名的规则和规约
    变量这样创建/声明:
    数据类型 变量名字; 比如: int a;或者String b;
    注意:变量是一个空间,可以只创建空间不存放内容,变量空间创建后没有默认的内容,是空的,空的变量空间不能拿来使用,会出现编译错误
byte x;//声明一个变量空间,空间名叫x,空间内要求存储的数据类型是byte整数
x=1;//讲一个1赋值到x空间内进行存储

也可以写成一句:

byte x = 1;
  • 变量空间x存储在栈内存里
  • 常量1存储在常量池(即常量缓冲区)里
    计算机底层做了这些:

1.在硬盘先创建一个文件Test.java
2.文件上的内容是我们编写的源代码:(向计算机发出指令)

public class Test{
	public static void main(String[] args){
		byte x;
		x=1;
	}
}

3.将Test.java源文件—>编译—>成为Test.class文件,这个文件里的内容我们看不懂,留给计算机识别
4.在内存中执行:将硬盘上的Test.class内容加载到内存里
5.我们写好的指令会执行内存的空间,赋值、变化。。。
在这里插入图片描述

需要注意:float x = 3.4F;
long y = 2147489999L;//如果超过int的取值范围2147483647就在后边加一个L

================================================

类型转化

类型之间的转换问题:

  • 同种数据类型之间是可以直接进行赋值操作的:
int a = 1;
int b = a;
float x = 3.4;
float y = x;
  • 数据类型不同的空间之间的赋值—>转换问题
    同种大数据类型之间才能发生转换
    基本类型----基本类型之间 可以直接转换(自动或强制)
    引用类型----引用类型之间 可以直接转换(自动或强制)–上转型 下转型
    基本类型----引用类型之间 不可以直接转换(间接转换–包装类/封装类)
  • 保证大数据类型一致的前提下:

1、基本类型----基本类型

保证大数据类型相同的前提下---->小数据类型相同的情况下:(比如都是整型或都是浮点型,比较的是内存空间的大小)
byte a= 1;
int b = a;//将一个小空间的值存到大空间里,自动直接转化  
int a = 1;
byte b = (byte)a;//将一个大空间的值存到小空间里,强制类型转换
float x = 3.4F;
double y = x;//自动直接转化  
double x = 3.4;
float y = (float)x;//强制类型转换

大空间变量可以直接存储小空间的数据
小空间变量不可以直接存储大空间的数据(需要强制类型转换)
转换过程写法都好用,如果转换过程中数值范围超过边界,数值可能会有损失:

int a = 1000;
byte b = (byte)a;//编译好用,执行后b存放的值一定发生变化

00000000 00000000 00000011 11101000---->只保留最后的8bit位

小数据类型不同的情况下:

(比如整型----浮点型):
两个比较精确程度,浮点型的精确程度更高,可以直接存放整数,反之需要强制类型转换(强行将小数点之后的部分去掉,只保留整数):

float a = 1.0F;
int b = (int)a;//强制转化,出来b为1
float a = 1.9F;
int b = (int)a;//强制转化,出来b为1

任何一个浮点型都可以直接存放一个整数:

int a = 1;
float b = a;//自动转换

(比如字符型----整型):
每一个字符都对应一个Unicode码

char x = 'a';
int y = x;//可以转化,出来y为97
int x = 97;
char y = (char)x;//强制转化,出来y为a
byte x = 97;
char y = (char)x;//强制转化,出来y为a

布尔类型很特殊,不能与其他基本类型之间发生转化

2、引用类型----引用类型

可以直接转化(自动 强制)

3、基本类型----引用类型

不可以直接转化(间接-桥梁-包装类)

=========================================

运算符号

Java运算符:

运算符是用来指明操作数的运算方式,有两种分类:

按照操作数的数目来进行分类:

  • 单目 a++
  • 双目 a+b
  • 三目 (a>b)?x:y;

按照运算符的功能进行分类:

算术运算

例如 + - * / %(取余、取模)
++(自增) --(自减)
x++;//x=x+1;//x空间的值自增一个,即:将x变量空间的内容先取出,常量区取出1,进行计算,再次存回x空间(x在想要做交换的时候会产生一个临时的副本空间(备份))
++x;// 对于x空间内的值来讲都是一致的,最终的结果都自增了一个

int x = 1;
int y = x++;//++在后,先赋值(计算)后自增-->结果x=2,y=1(++在变量的后面,先备份后自增,将副本空间内的值赋给别人,也就是y)

在这里插入图片描述


int x = 1;
int y = ++x;//结果x=2,y=2(++在变量的前面,先自增后备份)

int a = 1;
a=a++;//a==?结果a=1

在这里插入图片描述


int a = 1;
for(int i=1;1<=100;i++){
	a = a++;
}//a==?最终结果a=1

int m = 1;
int n = 2;
int sum = m++ + ++n - n-- - --m + n-- - --m//m==?0 n==?1 sum==?2
赋值运算

= 是赋值符号,将等号右边的内容(值 引用)存入左边的变量空间内
+= -= *= /= %= 符合运算符

int x = 1;
x+=2;//结果x=3

int x = 1;
x=x+2;//结果x=3

byte x = 1;//常量1是32bit位的,但是=做了自动转化
x+=2;//结果x=3  
//+进行自动类型提升,然后加上2后为3,=再进行自动转化

byte x = 1;//常量1是32bit位的,但是=做了自动转化
x=x+2;//编译出错,类型从int转化成byte可能有损失

x空间的值取出来,从常量区取过来2,进行加法运算,结果重新存回到x变量空间内
x空间–>1 8bit 00000001
常量区–>2 32bit
00000000 00000000 00000000 00000010
+的作用是进行自动类型提升,即由8bit–>32bit
00000000 00000000 00000000 00000001
00000000 00000000 00000000 00000010
相加:00000000 00000000 00000000 00000011==3
所以将3重新存回到x变量空间,但是x是8bit位的,存不下,所以需要强制类型转化:

byte x = 1;//常量1是32bit位的,但是=做了自动转化
x = (byte)(x+2);

因为=后边是个表达式,所以需要强制转化,若果是个常量,就会自动转化


关系运算(也叫比较运算)

有 > >= < <= != ==(对象instanceof类)

  • 区分 = 和 ==

= 赋值符号 将=后面的内容(结果或值)存入左边的变量空间内
== 比较符号 比较==前边和后边的元素(值/引用)是否一致

  • 比较运算符的最终结果是啥:
    boolean布尔类型 true false
逻辑运算

&逻辑与(两个条件都true,最终就true) |逻辑或(两个条件有一个true,最终就true) ^逻辑异或(两个条件不一样最终就true) !逻辑非(将原来的条件的结果取反) &&短路与(当前面的条件的值的结果为false的时候会发生短路,最终结果是false;如果第一个条件的结果是true,那就跟&逻辑与一样计算。短路的是&&之后所有的计算过程,如果发生了短路,性能比&稍微好一点,&逻辑与和&&短路与从执行的结果来看没有任何区别,&&短路与不一定提高性能,只有当前面的条件为false的时候才会提高性能) ||短路或(当前面的条件的值的结果为true的时候会发生短路,最终结果是true;如果第一个条件的结果是false,那就跟&逻辑与一样计算。)
1、逻辑运算符前后连接的应该是两个boolean的值,最后的结果还是布尔类型的值

位(bit)运算

&按位与|按位或^按位异或~按位取反<<按位左位移>>按位右位移>>>按位右位移(无符号)
&按位与(比如3 & 5 = ?):

1、将3和5转化成二进制的表示形式
2、竖着按照对应的位置进行&|^计算(1当做true,0当做false)
3、将计算后的二进制结果转化为十进制

~按位取反

  • 知识补充:
    正数的原码、反码、补码是一样的。比如6:
    原码:00000000 00000000 00000000 00000110
    反码:00000000 00000000 00000000 00000110
    补码:00000000 00000000 00000000 00000110
    负数的反码在原码的基础上符号位不动,其余位取反,补码在反码的基础上加1。比如-6:
    原码:10000000 00000000 00000000 00000110
    反码:11111111 11111111 11111111 11111001
    补码:11111111 11111111 11111111 11111010
    计算机中不管是正数还是负数,存储的形式都是以补码存储的。反码是一种表示形式,取反是一种计算过程
    (每个位置都取反)
    所以6在计算机中的表示形式是:00000000 00000000 00000000 00000110
    当求~6 = ?时,取反得:11111111 11111111 11111111 11111001,转化为二进制是-7
    <<按位左位移(比如6<<1 = ?、6<<2 = ?):
    00000000 00000000 00000000 00000110
    00000000 00000000 00000000 00001100
    相当于将这个数乘以2的位移次幂
    <<按位右位移
    (正数时比如6>>1 = ?、6>>2 = ?)
    00000000 00000000 00000000 00000110
    00000000 00000000 00000000 00000011
    相当于将这个数除以2的位移次幂
    (负数时比如-6>>1 = ?、-6>>2 = ?)
    11111111 11111111 11111111 11111010
    11111111 11111111 11111111 11111101
    相当于保留符号位置,原来的符号位是1,还填1,然后再将二进制转化为二进制
    >>>按位右位移(无符号)(比如-6<<<1 = ?、-6<<<2 = ?):
    11111111 11111111 11111111 11111010
    01111111 11111111 11111111 11111101
    不保留符号位置,不管是什么都填0
    ======================================

Java体系

  • 基础部分 JavaSE
    面向对象的编程思想 ArrayBox LinkedBox
    集合 String
    I/O流技术 MVC 缓存 文件–数据库 事务 反射注解 IOC
  • Level One
    数据库 本质就是文件
    JDBC 本质就是I/O 手动设计一个ORM–原 理 MyBatis
    WEB 本质就是Socket IO String
    手动设计一个容器(服务器)
    Tomcat
    Servlet JSP解析—>手动设计一个WEB框架
    Filter AJAX
    *Level Two
    框架部分
    SSM: Spring SpringMVC MyBatis
    SSH: Spring Struts Hibernate
    Linux Maven Git SVN
  • 分布式 大数据
    ==================================

Java语法结构1

顺序结构

分支结构

单分支if

if结构:

if(值--boolean型)
	{单行语句;}/{多行语句}//执行单行或多行

if else结构:

if(条件){
	代码1
}else{
	代码2
}

嵌套结构:

if(){

}else if(){

	}else if(){
			
		}else{

		}	

知识补充:Scanner类的引用:
lib文件夹会提供一个类库,有一个Scanner类,也就是开发者会给我们提供一个好的类文件Scanner.java,我们引用就行。
想要利用Scanner类需要如下三步:
1、在类上边的第一行导入包:
import java.util.Scanner;
2、需要输入之前new一个对象:
Scanner 对象名 = new Scanner(System.in);
3、通过 对象名.方法 让他来做事:
int = nextInt();//读取输入的信息,这个是读取输入的数字类型的文字
String = nextLine();//读取输入的信息,这个是读取字符串
比如:

import java.util.Scanner;//导包
Scanner input = new Scanner(System.in);//创建对象
System.out.printIn("请您输入一个数字:");
int Day = input.nextInt();//对象调用一个方法,这个方法的返回值是day

多分支switch

switch(值){//这个值可以是byte short int char类型的
	case 值1:
		代码1;
		break;//可有可无
	case 值2:
		代码2;
	default:
		代码;
}

循环结构

有for while do…while,就是重复不停的做同样的事情,需满足三个条件:初始值、终点判定条件、变化量

for结构

for(1初始值;258终点判定条件;47变化量){
36执行好多代码;
}
这三个条件不是必须都在括号里,将初始值放在外边,会使循环的生命周期更长一点

public class A{
	public static void main(String[] args){
		for(int round=1;round<=5;round++){
			System.out.println("跑到第"+round+"圈啦");
		}
		//循环执行完毕的时候,round=6
		System.out.println("循环执行完毕"+round);
		//但是运行结果却显示错误:找不到符号,变量round未找到。
	}
}

这个就涉及到了变量的生命周期问题,变量是栈内存中开辟的一块空间,从生命开始创建出来,用完就回收了。因为for循环允许将这三个条件放进括号,所以应该这样:

public class A{
	public static void main(String[] args){
		int round=1;
		for(;round<=5;round++){//;不能省略
			System.out.println("跑到第"+round+"圈啦");
		}
		//循环执行完毕的时候,round=6
		System.out.println("循环执行完毕"+round);
		//运行结果显示:round=6
	}
}

所以round=1;放在上边放在下边对循环的整个执行没有影响,生命周期却得到了扩充。

public class A{
	public static void main(String[] args){
		int round=1;
		for( ;round<=5; ){//;不能省略
			round++;//这样的话输出的时候第一次是跑到了第2圈,然后是3,4,5,6
			System.out.println("跑到第"+round+"圈啦");
		}
		//循环执行完毕的时候,round=6
		System.out.println("循环执行完毕"+round);
		//运行结果显示:round=6
	}
}

double Math.pow(double a,double b);//计算a的b次方的方法

循环嵌套

import java.util.Scanner;
public class DrawStar{//画*,行数也是每行*的个数
	public static void main(String[] args){
		Scanner input = new Scanner(System.in);
		System.out.println("请您输入*的行数:");
		int count = input.nextInt();
		for(int i=1;i<=count;i++){//i控制的是*的行数
			for(int j=1;j<=count;j++){//j控制的是每一行*的个数
				System.out.print("*");
			}
			System.out.println();
		}//这是个双层嵌套循环,执行的次数是内外层循环次数的乘积
	}
}
//运行结果:
4
****
****
****
****
import java.util.Scanner;
public class DrawStar{//画*
	public static void main(String[] args){
		Scanner input = new Scanner(System.in);
		System.out.println("请您输入*的行数:");
		int count = input.nextInt();
		for(int i=1;i<=count;i++){//i控制的是*的行数
			for(int j=1;j<=i;j++){//j控制的是每一行*的个数
				System.out.print("*");
			}
			System.out.println();//换行
		}//这是个双层嵌套循环,执行的次数是内外层循环次数的乘积
	}
}
//运行结果:
4
*
**
***
****
import java.util.Scanner;
public class DrawStar{//画*
	public static void main(String[] args){
		Scanner input = new Scanner(System.in);
		System.out.println("请您输入*的行数:");
		int count = input.nextInt();
		for(int i=1;i<=count;i++){//i控制的是*的行数
			for(int j=1;j<=count-i;j++){//画占位符
				System.out.print(" ");
			}
			//这两个j是可以一样的,因为循环结束会清空内存
			for(int j=1;j<=i;j++){//画星星,j控制的是每一行*的个数
				System.out.print("*");
			}
			System.out.println();
		}//这是个双层嵌套循环,执行的次数是内外层循环次数的乘积
	}
}
//运行结果:
5
    *
   **
  ***
 ****
*****

补充: 转义字符\:可以将\后的一个字符发生转换,可以转换特殊的符号,比如 ’ " \ ,还可以转换特殊的字母,比如 \n(表示换行) \r(表示回车) \t(表示制表符,当做表格来处理或者做一个前面空格的缩进)
比如要想输出helloworld,就这样:

System.out.println("helloworld"); ==>helloworld

但是要想输出"helloworld"的话,由于英文里""是不区分左右的,所以计算机会识别错误,所以需要用到转义字符:

System.out.println("\"helloworld\""); ==>"helloworld"
System.out.println("hello\nworld");
==>hello
   world
System.out.println("helloworld"); ==>hello	world

for循环

  • for(1初始值;258终点判定条件;47变化量){
    36执行好多代码;
    }
    这三个条件不是必须都在括号里,将初始值放在外边,会使循环的生命周期更长一点
    1初始值;
    for(;258终点判定条件;){
    36执行好多代码;
    47变化量;
    }
    break:终止循环
    continue:终止这一次的循环,继续执行下面的循环

while循环

先判断再执行,条件不满足就不执行了
初始值;
while(终点判定条件){//只允许写一个终点判定条件
执行好多代码;
变化量;//在上在下的顺序对程序执行的结果是不一样的
}

do…while循环

先执行再判断,条件不满足的话,至少还可以执行一次
初始值;
do{
执行好多代码;
变化量;//在上在下的顺序对程序执行的结果是不一样的
}while(终点判定条件)

==========================================

数组

  • 数组是一组数据类型相同的数据的组合,将这些数据统一管理起来。
  • 数组本身是一个引用数据类型,数组内存储的类型可以是基本类型,也可以是引用类型。
    ##数组的定义(声明)
  • 数据类型[] 数组名字;
    int[] x;
    char[] y;
    boolean[] z;
    String[] m;

此外,数组的声明有三种写法:
int[] x;—>更规范
int x[];
int []x;

数组的赋值(初始化)

  • 静态初始化
    有长度,有元素内容
    int[] array = new int[]{10,20,30,40,50};
    也可以写为:
    int[] array = {10,20,30,40,50}
    还可以写为:
    int[] array;
    若干行代码;
    array = new int[]{};
  • 动态初始化
    有长度,没有元素,并不是真的没有元素,是默认值
    int[] array = new int[5];
    整数默认值----0
    浮点数默认值----0.0
    字符型默认值----0对应的char值 97-a 65-A 48-‘0’
    布尔型默认值----false
    引用数据类型默认值----null

数组元素的访问

存值、取值

  • 通过元素在数组中的位置index索引(下标)来访问.
    array[index];
  • 索引是有范围的,index索引从 0 开始到 数组的长度减一 结束。
    [0,数组长度-1]

如果数组索引超出数组范围的话,会出现异常:Array Index OutOf Bounds Exception----数组索引越界
比如:

public class TestArray{
	public static void main(String[] args){
		int[] array = new int[]{10,20,30,40,50};
		//从数组内取得某一个位置的元素
		//int value = arrray[4];
		//System.out.println(value);
		//向数组内的某一个位置存入元素
		//array[3] = 400;
		//将数组中的每个元素都取出来
		//正常的for循环
		for(int index=0;index<5;index++){
			int value = array[index];
			System.out.println(value);
		}//数组的遍历
		//加强的for循环
		for(int value:array){
			System.out.println(value);
		}//数组的遍历
	}
}

数组元素的遍历(轮询)

  • 通过循环的方式访问数组的每一个元素 for循环、while循环

  • 正常的for循环
    for( ; ; ){
    }
    有三个必要条件
    通过index直接访问数组的某一个位置,存取值都行
    不好在于写法相对麻烦

  • JDK1.5版本之后,出现了一个新的特性,叫增强for循环(加强for循环,forEach)
    for(自己定义的变量(接收数组内的每一个元素):要进行循环的数组名(遍历的数组array)){
    }
    增强的for循环有两个条件:用来取值的变量,用来遍历的数组,没有index索引
    写法相对容易,但是只能取值,不能存值,没有index索引,找不到元素到底是哪个一个

基本类型和引用类型在数组结构上的区别

  • 所有的变量空间都存储在栈内存
  • 变量空间可以存储基本数据类型,也可以存储引用数据类型
  • 存储基本数据类型的变量空间存储的是值,传递的就是值,一个变量改变的话,另一个不变
  • 存储引用数据类型的变量空间存储的是地址(引用),传递的就是引用,一个变量地址对应的值改变,另一个就跟着改变
    在这里插入图片描述
public class TestArray{
	public static void main(String[] args){
		int a=10;
		int b=a;
		b=100;
		System.out.println(a);//?  10

		int[] x = new int[]{10,20,30};
		//变量是栈内存中的一个小容器,类型定义了只能存这种东西,这个容器中只能存一份(一个值)
		//见到new关键字,相当于在堆内存中申请开辟一块新的空间
		//数组在堆内存中的空间形态,是一串连续的地址
		int[] y=x;
		y[0] = 100;
		System.out.println(x[0]);//?  100
	}

}

创建一个数组,存储1-100之间的偶数:

public class SaveNumber{
	public static void main(String[] args){
		//1.首先要创建一个数组
		int[] array = new int[50];
		//2.需要将1-100之间的偶数存到数组里边
		for(int i=0;i<array.length;i++){
			array[i] = 2*i+2;
		}
		//3.输出验证看是否存入正确
		for(int v:array){
			System.out.println(v);
		}
	}
}

ps: 在这段代码中,创建数组用的是动态初始化的形式。当元素的个数比较少的时候用静态初始化,当元素的个数很多且有规律,用动态初始化。元素很多且没规律用静态。
总结:
1.数组本身是一个引用数据类型
2.数组是在堆内存中的一串连续的地址存在
3.堆内存的数组空间长度一旦确定,就不能再次发生改变
4.栈内存的变量中存储的是数组的地址引用
5.数组内部存储的类型可以是基本数据类型,也可以是引用数据类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值