1. JavaSE入门

Java学习文档

1 基础知识

1.1 软件

软件就是计算机数据与指令的集合。软件 = 数据 + 指令 + 文档。

软件的目的是提高人与计算机交流的效率,方便人与机器交互。

1.2 常用命令

现在人机交互的方式分为图形化界面交互和命令式交互。

图形化界面简单直观,容易操作;使用命令的方式需要记住命令,操作麻烦。

但是在程序开发中,使用命令更加高效,有时使用一条命令就能完成若干的操作。我们也需要学些简单的命令。

在Windows中执行命令需要在CMD窗口中输入命令。打开控制台的方法:Windows + R键,输出cmd并回车。

常用的DOS命令:

> 盘符: :进入指定的盘符。

> dir:列出当前目录下文件和文件夹

> md:创建目录

> rd:删除目录,不能删除非空的文件夹

> cd:进入指定目录,cd ..表示退回上一级,cd \表示退回到根目录。

> echo "hello java" > a.txt:将文本写入到指定文件,将会创建文件

> type a.txt:显示文件内容

> del:删除文件

> exit:退出控制台

> cls:清空屏幕

另外,在控制台中可以用:

*和?通配符;按下tab进行命令补全;上下方向键显示历史命令。

2 Java简介

Java是SUN (Stanford University Network,斯坦福大学网络)公司于1995年推出的一门高级编程语言。Java原是印度尼西亚爪哇岛的英文名称,因盛产咖啡而闻名。Java最初目标在于家用电器等小型系统的编程,随着市场的变化,Java着眼于网络应用的开发。

1995年5月,JAVA语言诞生。

2004年9月,J2SE 1.5发布,这是Java发展史上的一个里程碑。为了表示该版本的重要性,J2SE 1.5更名为Java SE 5.0。

2005年,JAVA版本正式分为JAVA EE(企业级),JAVA SE(基础)和JAVA ME(嵌入式)。我们现在学习的是Java SE,以后要学Java EE。必须先学好Java SE基础才能进行Java EE或者Android应用的开发。

2006年12月,Sun发布了Java 6.0。

2009年,Oracle(甲骨文公司)收购了Sun公司。即现在Java归Oracle管理。

2011年7月,Oracle发布了Java 7。

2014年,甲骨文公司发布了Java 8正式版。

2.1 Java的跨平台特性

这里着重讲Java的跨平台特性,语音的其他特性就不讲了,只能在学习中体会。
跨平台就是软件的运行不依赖于具体的操作系统。在一个操作系统下开发的应用,放到另一个操作系统下依然可以运行。而Java就具有这样的特性,Java语言编写成的程序在不同的OS上都可以运行,“一次编写,处处运行”。

而C语言的跨平台性就不好,在Windows上编译生成的C语言程序,在Linux系统下是不能运行的。至少也要将源代码再编译生成不同的目标代码,况且,不同OS的系统调用API不同,就更加大了跨平台的难度。

Java的跨平台是通过JVM(Java Virtual Machine,Java虚拟机)来实现的。

JVM相当于是一个用软件模拟的计算机。Java源程序会编译成.class字节码文件。.class字节码文件由JVM解释运行。因此,只要为每种操作系统提供不同的JVM,就能实现跨平台。即JVM拿到的是同一个字节码文件,由JVM适应不同的OS。图解:

3 搭建Java开发环境

开发Java需要安装JDK,即Java开发工具(Java Development Kit)。JDK是整个Java的核心,包括了Java运行环境、Java工具和Java基础类库。

3.2 安装JDK

首先在Oracle官网https://www.oracle.com找到JDK下载页面。

之后在Java SE的页面,点击下载的图标,出现下面界面,要按照图中所示操作,即接受协议再下载符合自己电脑的版本:

下载完后,点击安装程序进行安装。安装时注意选择安装路径,路径中不要有空格和中文。安装时,把“公共JRE”这个组建去掉,不予安装,因为JDK中已经包含了JRE,不再需要额外的JRE。

说明:JRE就是Java运行时环境(Java Runtime Environment)。JRE用于支持运行Java程序,包括JVM和运行Java程序需要的核心类库。如果只是使用Java应用的用户,则只要安装公共JRE即可。

3.2 JDK安装目录介绍

bin目录:存放Java编译器、解释器等工具。

db目录:这里是JDK附带的一个轻量级数据库,名叫Derby。

include目录:存放调用系统资源的接口文件。

jre目录:存放Java运行环境文件。

lib目录:存放Java类库文件。

src.zip文件:是JDK Java类的源码。IDE会找到这个文件,以便在IDE中查看JDK源码。

3.3 配置环境变量

3.3.1 环境变量及其作用

环境变量用于存储操作系统级别的变量。环境变量分为系统变量和用户变量,系统变量可被系统中的所有用户共享使用;而用户变量只能被当前用户使用。因此每个用户都能配置自己的用户变量。用户也能设置系统变量,但是建议将自行配置的环境变量放在自己的用户变量中,这样比较清晰,互不影响。

通过实践表明环境变量能在系统中使用。首先查看下本机的环境变量:桌面 – 右键“此电脑” – 属性,出现下面界面,点击“高级系统设置”:

在新界面中(默认“高级”选项卡),点击“环境变量”按钮:

新界面显示的内容就是本机的用户变量和系统变量。

我们可以用这里的变量,在Windows中环境变量的变量名不区分大小写。比如用户变量里的“TEMP”表示本用户的临时目录,在文件管理器地址栏中输入%TEMP%回车就能进入此目录。%变量名%就表示引用这个变量。同样在控制台中执行echo %TEMP%也能显示此路径。
另外,还有一个用户变量叫USERPROFILE,这个变量在界面中隐藏了。这个变量指向用户的主目录,用这个有时很方便。

3.3.2 Path环境变量

前面说JDK下的bin目录是一些工具,我们需要使用。比如进入该目录下打开控制台,执行java命令会有一系列使用命令的提示。但是如果不在此目录下,该命令就无效:

但是,一些系统命令,无论在什么路径下都能使用,比如calc(打开计算器)、diskpart命令等。

为了在其他路径下也能使用JDK中的命令,需要配置Path环境变量。

PATH变量是一个特殊变量,一旦把一个路径添加到Path环境变量中,那么该目录下的命令就能在控制台的任意路径下使用。系统命令就是在系统Path命令中设置了才能在任何地方使用的。

我们可以在系统变量的Path变量中添加上JDK\bin目录,但是前面说过,我们一般把自行配置的变量配置到用户变量中。

在原有路径之后添加自己的路径,注意路径之间用英文半角分号隔开!

然后点击确定,并且下层界面也要依次点确定。

之后,需要重新启动控制台,这时在任意路径下都能使用java命令了。

但是一般标准的做法是在系统变量中增加一个变量,名字叫“JAVA_HOME”,这个就是JDK的根目录,然后Path变量引用这个JAVA_HOME变量。这样的设置有利于以后使用大多数IDE软件,因为很多软件会先检测JAVA_HOME这个变量。

(1)首先在“环境变量”界面新建一个用户变量,名叫“JAVA_HOME”,值是JDK根目录。(以后的很多工具也最好配置工具的根目录,都是以_HOME结尾。标准做法。)

(2)然后添加Path环境变量(之前直接设置的JDK\bin可以删除了),值为“%JAVA_HOME%\bin”,就是指向JDK的bin目录。这也说明了变量间可以相互引用,还用通过 “%变量名%”引用。

(3)点击确定,然后重启控制台,即可使用java中命令了。

还需要了解一下命令搜寻的顺序:

(1)首先在当前目录下寻找命令,如果找不到就寻找环境变量中的路径。

(2)先寻找用户Path变量中的路径,若找不到就寻找系统Path变量中的路径。

3.3.3 设置临时环境变量

用set命令可以查看或设置临时变量,用法如下:

Set:查看所有环境变量信息。会整合用户变量和系统变量,比如用户变量和系统变量都有path变量。

Set 变量名:查看具体一个环境变量的值。

Set 变量名= :清空一个环境变量的值。

Set 变量名=具体值:给指定变量定义具体值。

若想在原有环境变量值基础上添加新值,则通过%变量名%引用原有值,然后加上新值再设置给该变量即可。

例如给path环境变量加入新值

Set path=新值;%path%

注意:用set命令配置的环境变量只在当前控制台窗口有效,一旦窗口关闭,该临时的配置就消失了,还会变为自行设置的值,只是临时起作用。

4 Java程序入门

4.1 编程前的准备

我们首先用简单的工具写Java代码并编译运行。首先要了解纯文本文件和简单的文本编辑器。

windows中自带一个叫记事本的软件,记事本保存文档的格式是txt格式,就是英语text的缩写。我们称这种文件为“纯文本文件”。这是因为纯文本文件只能保存文本内容,不能保存文本的样式(虽然可以通过设置软件来使看到的字体变大等)。而docx(Microsoft Office)等文档不仅能保存文本内容,还能保存文本的各种复杂样式。所以,docx和txt存储同样的文本内容,docx文件比txt的大。而且docx文件无法用记事本打开,会乱码,无法解析因为docx有特定的格式。

因此,纯文本文件就是这样的文件:

1) 只有文本,没有样式;

2) 用记事本等纯文本编辑器可读,不是乱码。

而源代码都是纯文本格式的,里面只写代码内容,包括java源文件、html文件等等。只是我们编辑html时用文本编辑器,而用户使用html时是使用浏览器浏览的。可以设置打开方式。

Windows自带的记事本不太好用,我们使用Notepad++这款文本编辑器。

4.2 第一个Java程序

首先选定一个目录,创建一个纯文本文件,叫Demo.txt。注意,一定要设置文件扩展名为可见,因为我们要把文件扩展名改为Demo.java,否则扩展名就是Demo.java.txt了,是错误的。

然后将Demo.txt改名为Demo.java。并用Notepad++打开(右键用Notepad++打开)。编写如下内容:

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

这段代码的作用是在控制台打印出“Hello World”,目前我们写的都是控制台程序。

Class用户定义类,这是面向对象的内容,先写着。Demo类中有main方法,这是主方法,args是接收的命令行参数,因为参数有多个,所以用字符串数组接收(Java中String表示字符串类)。public static先这样写着,是面向对象的内容。System.out.println()作用是打印一行数据。

通过上面的分析,发现Java也是类C语言,因此面向过程的大部分内容都和C是一样的,下面就带过了。

4.3 程序的编译和运行

写完了上面的代码,需要将代码进行编译并运行,这时需要使用JDK\bin下的工具,如果不能使用这些工具的话,则说明环境变量没有配置好。

(1)先用javac工具将源文件编译成class字节码文件。使用命令:

javac 源文件。例如此例中使用:javac Demo.java。这样就能得到字节码文件。

(2)有了字节码文件,就能运行程序了。使用java工具运行该字节码。

java 字节码文件名(不要加.class扩展名),例如:java Demo。

从上述看出,Java是先编译成字节码文件,然后由JVM解释执行字节码文件。由JVM解释执行保证了Java的跨平台性。做下对比:

C语言是编译型语言,直接编译成目标平台的程序,可直接运行;

JavaScript是编译型语言,不需编译,直接由浏览器的JavaScript引擎解释执行。

5 Java面向过程编程的新知识

这里总结概述Java中编写面向过程编程的注意点,主要将新特点,和C语言同样之处不再多说。

5.1 命名规则和注释

标识符的命令不能是关键字,像class、int、float等都是关键字,另外,还要遵循以下规则:

1. 标识符由unicode字符(推荐英文)、数字(0~9)、下划线(_)和美元符号($)组成。
  2. 不能以数字开头
  3. 严格区分大小写

标识符的命名规则要求“见名知意”。常用的命名规则:

1. 包(package)名:包其实就是文件夹,用于管理多个类,包名采用小写,如:com.xzit.xdxy
  2. 类或者接口:Pascal规范,例如StudentInfo。
  3. 方法/变量名:camel规范,例如studentAge。
  4. 常量:若常量名是一个单词,则全部字母大写,若是多个单词,则全部字母大写,中间用下划线_隔开。

Java中的注释:

//单行注释

// 多行注释

文档注释: /** … */,这种注释稍后再说明。

注意多行注释不能嵌套和注释的调试作用。

5.2 数据类型

基本数据类型:

byte(1字节) 数值范围:128~127

short(2字节)

int(4字节)

long(8字节),定义long类型,可在数据后加上大写字母L以便区分。

float(4字节),定义float类型,必须在数据后加上字母F或者f,否则浮点数默认是double类型的,强转成float会丢失精度,因此报错。

double(8字节)

char(2字节,unicode编码)

boolean(1字节),值只有true和false,布尔类型。

注意不要使用未初始化的变量。

不同进制的数据在Java中的表示:

1. 二进制:以0b开头
  2. 八进制:以0开头
  3. 十六进制:以0x开头

Java中也能使用转义字符。和C相同。

5.3 数据类型转换

1.自动类型转换(隐式)

2.强制类型转换(显式):(变量类型)变量名。注意可能会损失精度。

3.boolean类型不能转换为其他的数据类型

下面是例子:

例1:

public class Demo {
    public static void main(String[] args) {
        short a = 1;
        a = a + 1; // 错误,因为a先加1,会自动转换成int类型
        short b = 2;
        b++; // 正确,其中隐含了一个强制转换
    }
}

例2:

public class Demo {
    public static void main(String[] args) {
        byte b1 = 3, b2 = 4, b3;
        b3 = b1 + b2; // 错误
        /*
        为什么byte b1 = 3不报错,而将两个byte相加再赋值给一个byte就会报错(仅限于byte类型)?
        byte b1 = 3是正常的,因为3在byte范围内,赋值时直接将3作为byte类型给b1.
        b3 = b1 + b2报错是 java 的机制导致的:
        java在对byte类型运算时,会将其转换为int类型,两个int类型相加,赋值给byte类型肯定会报错的。
         */

        byte a = 3 + 4;
        // 这个不报错。
        // 3和4是常量,在编译时编译器就讲3+4解析成常量7赋值给变量a了。
        // 7在byte范围内,直接赋值,这是编译器的优化。
    }
}

5.4 运算符

(1)算术运算符:加减乘除、取余、自增自减。

例1:符号+还能用于连接字符串。加法符号+是从左向右结合,只要符号左右两边不都是数字,就是连接字符串。语句System.out.println();用于输出信息。

public class Demo {
    public static void main(String[] args) {
        System.out.println("hello"  + 'a' + 1);
        System.out.println('a' + 1 + "hello");
        System.out.println("5 + 5 = " + 5 + 5);
        System.out.println(5 + 5 + " = 5 + 5");
    }
}

运行结果:

helloa1
98hello
5 + 5 = 55
10 = 5 + 5

(2)取模后,结果的正负取决于被除数。利用取余,可以判断一个整数的奇偶等
  例2:取余结果的正负号。

public class Demo {
    public static void main(String[] args) {
        System.out.println(-10 % 3);    // -1
        System.out.println(10 % -3);    // 1
        System.out.println(-10 % -3);   // -1
    }
}

例3:判断整数奇偶。

public class Demo {
    public static void main(String[] args) {
        int num = 23;
        if(num % 2 == 0) {
            System.out.println(num + "是偶数");
        } else {
            System.out.println(num + "是奇数");
        }
    }
}

例4:如果今天是星期五,那么1000天后是星期几?

public class Demo {
    public static void main(String[] args) {
        int today = 5; // 今天周五
        int after1000 = (today + 1000) % 7;
        System.out.println("1000天后是周" + after1000);
    }
}

(3)赋值运算符=和复合运算符,比如sum += 1.

(4)比较运算符的结果是boolean类型,只有true和false两种结果。例如等于==,不等于!=,大于>,小于<,大于等于>=和小于等于<=。

(5)逻辑运算符:与(&和&&,&&是短路与),或(|和||,||是短路或),非(!)和异或(^,即左右两边表达式都为true或false时,结果为false,否则结果为true,即一个true一个false)

public class Demo {
    public static void main(String[] args) {
        System.out.println( (5 > 3) ^ (4 > 2) );  // 表达式均为true,结果为false
        System.out.println( (5 > 3) ^ (4 < 2) );  // 结果为true
    }
}

(6)位运算符。&、|和^除了可以作为逻辑运算符,也可以作为位运算符。位运算是对两个操作数中的每一个二进制位都进行运算。另外,~是取反操作,只有一个操作数。

一个数异或同一个数两次,结果还是那个数,可以用这个规律进行数据的加密。

(7)移位操作符:左移<<,右移>>,无符号右移>>>(被移位二进制最高位无论是0或者是1,空缺位都用0补)。

左移:被移除的高位丢弃,右边空缺位补0。左移就相当于乘以2的位移位数次幂。右移相当于除以2的移动位数次幂。

最有效率的方式算出2乘以8:2 << 3.

右移:被移位的二进制最高位是0,右移后,空缺位补0;若最高位是1,空缺位补1。

无符号右移:被移位二进制最高位无论是0或者是1,空缺位都用0补。

(8)三元运算符

(9)优先级。使用括号能改变优先级。

5.5 流程控制

流程控制还是:顺序、选择和循环结构。使用的关键字的用法都是相同的,可以使用if、else、switch、三元表达式、do…while、while、for、break和continue。

switch语句的控制表达式的数据类型只能是byte、short、char、int(不能是long类型)、枚举类型和String类型(不能是StringBuffer或StringBuilder类型)。

例1:判断输入的月份有多少天。【学习Scanner获取用户输入和判断闰年】

说明:获取从键盘输入的数据,需要用到Scanner类:

1. 导包:import java.util.Scanner;

2. 创建对象:Scanner sc = new Scanner(System.in);

3. 获取int类型数据:int x = sc.nextInt();

import java.util.Scanner;

public class Demo {
    public static void main(String[] args) {
        int userInput; // 记录用户输入的数据
        Scanner sc = new Scanner(System.in); // 用System.in创建Scanner对象
        do {
            System.out.println("请输入月份:(输入-1退出程序)");
            userInput = sc.nextInt(); // 获得输入的年份
            // 使用switch
            switch(userInput) {
                case 1:
                case 3:
                case 5:
                case 7:
                case 8:
                case 10:
                case 12:
                    System.out.println(userInput + "月有31天");
                    break;
                case 4:
                case 6:
                case 9:
                case 11:
                    System.out.println(userInput + "月有30天");
                    break;
                case 2:
                    System.out.println("请输入年份");
                    int year = sc.nextInt();
                    int days = ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0)) ? 29 : 28;
                    System.out.println(year + "年" + userInput + "月有" + days + "天");
                    break;
                case -1:
                    break;
                default:
                    System.out.println("输入月份错误");
                    break;
            }
        } while(userInput != -1);
    }
}

例2:猜数字游戏。【学习生成随机数】
  说明:使用Math.random()方法能生成一个[0.0, 1.0)之间的随机数,现在想生成[1, 100]之间的随机数,则用式子:(int)(Math.random() * 100 + 1) 来生成。每次运行程序生成的数字是不一样的,说明Math.random()是以当前时间作为种子。

import java.util.Scanner;

public class Demo {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int number = (int)(Math.random() * 100 + 1);
        int userInput = number--; // 防止初始化数据与number一致
        do {
            System.out.println("请输入你猜的数字:");
            userInput = sc.nextInt();
            if(userInput > number) {
                System.out.println("猜的大了");
            } else if (userInput < number) {
                System.out.println("猜的小了");
            } else {
                System.out.println("猜中了!");
            }
        } while (userInput != number);
    }
}

例3:跳出或者结束一个最内层循环用break/continue,如果想跳出/结束多个循环,则使用标签跳转。break和continue都可以结合标记使用:

public class Demo {
    public static void main(String[] args) {
        outer:
        for (int x = 0; x < 3; x++) {
            for (int y = 0; y < 4; y++) {
                break outer;
            }
            System.out.println("hello");
        }
    }
}

6 扩展:用异或对文件加密/解密

import java.io.*;

public class Demo {
    /**
     * 由于加密和解密都是对目标文件异或,因此,只有一个主程序。
     * @param args 定义此程序的参数1是输入文件,参数2是输出文件
     */
    public static void main(String[] args) throws IOException {
        // 参数个数错误提示
        if(args.length < 2) {
            System.out.println("请正确使用参数!");
            System.out.println("参数用法:");
            System.out.println("参数1:输入文件,参数2:输出文件,参数3:加密/解密的数字");
            System.out.println("例子:mypwd d:/1.txt d:2.txt 21");
            return;
        }
        String inFilePath = args[0];
        String outFilePath = args[1];
        int code;
        try {
            code = Integer.parseInt(args[2]);
        } catch (Exception e) {
            System.out.println("加密/解密的密码必须是数字");
            return;
        }

        // 根据路径创建文件
        File inFile = new File(inFilePath);
        File outFile = new File(outFilePath);
        // 输入文件不存在提示
        if(!inFile.exists()) {
            System.out.println("文件: \"" + inFilePath + "\"  不存在");
        }

        // 根据File对象创建输入和输出流
        FileInputStream input = new FileInputStream(inFile);
        FileOutputStream output = new FileOutputStream(outFile);

        // 读取到就把数据异或
        int content = 0;
        while((content = input.read()) != -1) {
            // 异或到输出流
            output.write(content ^ code);
        }
        // 关闭资源
        output.close();
        input.close();
    }
}

7 方法

7.1 方法的格式

Java中的方法就是函数,Java中函数不需要在使用之前声明,直接定义即可使用。Java中方法的格式:

修饰符 返回值类型 方法名(参数类型和参数名)

现在的阶段我们使用的修饰符就是public static。

7.2 方法的重载

在同一个类中,有一个以上的同名函数,只要函数的参数列表或参数类型不一样即可,与返回值无关, 这些统称为方法的重载。

方法的重载让我们可以定义重名的函数。

8 数组

8.1 数组的定义

定义的格式:

type[] arrayName;

type表示数组存储的数据类型,arrayName是数组名称。比如:

int[] arr;

表示的是定义了一个int类型的数组,数组名是arr,该数组存储int类型数据。

8.2 数组的初始化

数组的初始化有两种方法,根据需求来:

(1)int[] a = new int[3];

只指定长度,系统给初始值。int类型初始值是0,String初始值是null。

(2)int[] a = {1, 2, 3}; 直接给数组赋值。

8.3 访问数组元素和遍历

访问数组元素要注意数组越界问题:如果访问数组时,索引值小于0或者大于等于数组的长度,编译时不会报错,但是会有运行时异常:ArrayIndexOutOfBoundsException:N,N就是试图访问的数组索引。

空指针异常(NullPointerException):当一个对象为空null,而使用这个对象时,就会
产生空指针异常(运行时)。数组是一种引用类型,比如数组没有任何指向而访问其元素就会有空指针异常。

数组的length属性能得到该数组的长度,就是数组中元素的个数。常用这个和for循环来遍历数组。

8.4 内存分析

数组是引用类型,Java在存储基本类型(值类型)和引用类型变量时是不同的。
Java中有堆存储和栈存储。

栈存储局部变量(方法中的变量)中的值类型和任何变量的变量名。局部变量使用完毕后就会释放。
堆存储new出来的东西,然后把堆地址赋给栈中的变量。这样栈中的变量名就引用了堆中的地址。当一个堆中的数据没有引用时,Java的垃圾回收器(GC)就会回收并释放资源。
可以画图解释。以后的对象在内存里面的存储也是这样的。

8.5 数组中的算法

在数组中可以练习:查找最大值、排序等算法。这里实现一个二分查找法的算法实现。二分查找法的前提是这个数组是已经从小打大排好序的。

public class Demo {
    public static void main(String[] args) {
        int[] arr = {11, 22, 33, 44, 55, 66};
        System.out.println(myBinarySearch(arr, 3));
    }

    public static int myBinarySearch(int[] targetArr, int targetNum) {
        int head = 0;
        int end = targetArr.length - 1;
        int middle = (head + end) / 2;
        while(targetArr[middle] != targetNum) {
            if(head > end) {
                return -1;
            }
            if(targetNum > targetArr[middle]) {
                head = middle + 1;
            } else {
                end = middle - 1;
            }
            middle = (head + end) / 2;
        }
        return middle;
    }
}

就是如果不相等,就看这个中间的数和目标值哪个大,如果是中间的数大,那么目标值在中间数的左边,将尾指针移到中间数前面,否则将头指针移到中间数后面。如果某次头指针比尾指针还靠后,说明找不到这个数,返回-1.

8.6 二维数组

二维数组的每个元素就是一维数组。

二维数组举例:int[][] arr = new int[m][n];

m表示这个二维数组有多少个一维数组

n表示每一个一维数组的元素个数。例如int[][] a = new int[3][4].

内存图理解:

还可以这样进行动态分配:

int[][] arr = new int[3][];

arr[0] = new int[2];

arr[1] = new int[3];

arr[2] = new int[4];

这样的话,可以使每行的一维数组元素个数不一致。也可以这样初始化:

int[][] arr = { { 1 ,2 ,3 } , {4 ,5 }, { 6 } };

8.7 遍历二维数组

直接看代码:

public class Demo {
    public static void main(String[] args) {
        int[][] arr = {{1, 2, 3}, {4, 5}, {6}};
        // 遍历
        for(int i = 0; i < arr.length; i++) {
            for(int j = 0; j < arr[i].length; j++) {
                System.out.print(arr[i][j] + " ");
            }
            System.out.println(); // 换行
        }
    }
}

8.8 数组的特点

(1)数组只能存储同一种数据类型的数据。
  (2)数组会给每个元素分配一个索引值,从0开始。
  (3)数组一旦初始化,那么长度就固定了。
  (4)数组中的元素内存地址是连续的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,293评论 18 399
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • Java8张图 11、字符串不变性 12、equals()方法、hashCode()方法的区别 13、...
    Miley_MOJIE阅读 3,634评论 0 11
  • 半夜醒来,正好看到博雅大师兄推送的一篇文章《我只想把自己废掉——12岁女孩的自白》http://www.jians...
    冠世墨玉yanzi阅读 193评论 2 2
  • 虽然不知道你是谁,但是谢谢你让我知道你一直都在...... 前几天回了老家,室友说晚上有人在外头敲门,问是谁却没有...
    迷路路阅读 156评论 0 0