1.直接量
直接量是指在程序中由源代码直接指定的值。例如:int a = 3中,变量a所分配的初始值3就是一个直接量。
- 直接量的类型:
不是所有的类型都可以直接指定直接量,可以指定的直接量的一般只有三种类型,基本数据类型,字符串类型,null类型。- int类型的直接量: 在程序中直接给出的整数数值
- long类型的直接量: 整数数值后面加L就是long类型的直接量
- float类型的直接量:在一个浮点数后面加F就是float类型的直接量
- double类型的直接量: 直接给一个标准的小数形式的浮点数就是double类型的直接量
- boolean类型的直接量: 直接量只有true和false
- char类型的直接量:char类型的直接量有三种形式,分别是用单引号括起来的字符,转义字符和Unicode表示的字符
- String类型的直接量:双引号括起来的字符就是String类型的直接量
- null类型的直接量: 直接量只有null
null类型是一种的特殊的类型,只有一个值null,并且这个直接量可以赋值给任何引用类型的变量,用来表示这个变量中保存的地址为空,还未指向有效的对象
2.直接量的赋值:
通常是把直接量赋值给对应类型的变量。例如:
int a = 3;
long b = 4L;
char c = 'c';
double d = 5.6;
boolean e = true;
float f = 2.62F;
String g = "abc";
java支持数据类型的自动转换,但是String类型的直接量不能赋给其他变量,null类型的直接量可以直接赋值给人和引用类型的变量,包括String类型。boolean类型的直接量只能赋给boolean类型的变量,不能赋给其他任何类型的变量。
2. 逻辑控制
在学习控制结构之前,需要先了解块(block)的概念。
块是指由一对大括号括起来的Java语句。块确定了变量的作用域,块与块可以嵌套
不论哪种语言,都会提供两种基本的控制结构:分支结构和循环结构
1.顺序结构
任何编程语言中最常见的就是顺序结构,顺序结构就是从上到下依次执行,在前面的先执行,在后面的后执行.
2.分支结构
Java提供了两种常见的分支结构,if和switch.
if表达式语句:
第一种形式:
if(条件表达式){
.....代码逻辑
}
第二种形式:
if(条件表达式){
.....代码逻辑
}else{
//else语句可选,与最近的一个if组成一组
.....代码逻辑
}
第三种形式:
if(条件表达式){
.....代码逻辑
}else if(条件表达式){
.....代码逻辑
//可以有多个或者零个else if 语句 ,下面的else也可以省略
}else{
.....代码逻辑
}
switch分支语句:
switch(变量){
case 值:执行逻辑;break;
…..
default:要执行的语句;
}
- switch后面的(),里面需要的是一个具体的数值,类型:byte ,short,char ,int ,jdk1.5增加了枚举;JDK 1.7之后也可以是String类型
- break可以省略,但是会一直执行到遇到break才会结束
- default的作用就是所有case都不满足的时候执行,可以写在任意位置.
3.循环结构
循环语句在满足条件的情况下,重复执行某一段代码,这一段代码被称为循环体.
while循环:
while(循环条件){
//循环体
........
}
while循环在执行前会先检测条件,只有条件为true时才会执行循环体,若我们想程序最少执行一次,那么可以使用do ... while循环.
do{
//循环体
.......
}
while(循环条件);
for循环:
for循环是支持迭代的通用循环结构,利用每次迭代之后更新的计数器或者类似的变量来控制迭代的次数.
//for语句分为三个部分,第一部分通常用于对技术器的初始化,
//第二部分每次新一轮循环执行前要检测的循环条件,
//第三部分是指示如何更新计数器
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
中断流程控制语句:
break,作用于switch 和循环语句,用于跳出,或者称为结束.
continue:只作用于循环结构,跳过当前循环的剩余部分,跳到循环首部.跳出本次循环,执行下次循环.
3. 数组类型:
数组是编程语言中最常见的一种数据结构,它可以用于存储多个数据,一个数据被称为数组元素,通常可通过数组元素的索引来访问数组元素,包括元素赋值和取出数组元素的数据.
数组最大的特点就是长度不可变.因为一旦数组的初始化完成,数组在内存中所占的空间将被固定下来,即便把某个数组元素的数据清空,但它所占的空间依旧会被保留,依旧属于该数组,长度依旧没变.
数组也是一种数据类型,本身是一种引用类型,既可以存储基本数据类型的数据,也可以存储引用类型的数据,只要数组元素具有相同的类型就可以.
1.定义数组:
Java支持两种语法格式定义数组
类型[] 数据名称 例如:int[] data;
类型 数据名称[] 例如:int data[];
推荐使用第一种语法格式定义数组.第一种不仅具有更好的语意,也具有更好的可读性.
注意:数组是引用类型,定义数组,仅仅是定义了一个引用变量,并未指向任何有效的内存空间,所以还没有内存空间来存储数组元素,因此数组还不能使用,只有对对象进行初始化后才可以使用.
2.数组初始化:
数组必须先初始化才可以使用.所谓初始化就是为数组的数组元素分配内存空间,并为每个数组元素赋初始值.
数组初始化的两种方式:
a.静态初始化: 初始化时由程序员显式的指定每个数组元素的初始值,由系统决定需要的数组长度.
b.动态初始化: 初始化时程序员只指定数组长度,由系统为数组元素分配初始值.
静态初始化语法格式如下:
//定义一个int类型数组
int[] arr;
//静态初始化,初始化只指定数组元素的初始值,不指定数组长度
arr = new int[]{1,2,3,4,5};
//定义一个Object类型的数组
Object[] oArr;
//静态初始化,初始化时数组类型时定义数组元素类型的字类
//Java支持字类与父类的继承关系,子类实例是一种特殊的父类实例.
oArr = new String[]{"a","b","c"};
//在定义数组的时候同时初始化数组.在实际开发中,主要采用此种方式
int[] a = {6,7,8,9,10};
动态初始化语法格式如下:
//动态初始化:数组定义和初始化同时完成.只指定数组的长度,即为每个数组元素
// 指定所需的内存空间,系统负责给这些元素分配初始值
int[] arr = new int[5];
//初始化数组时元素类型时定义数组时元素类型的字类
Object[] oArr = new String[8];
3.数组的使用:
//数组最常用的用法就是访问数组元素,包括对数组元素进行赋值和访问数组元素的值
//访问数组元素通过索引下标实现,数组的下标从0开始
int[] arr = new int[]{1,2,3,4,5};
//获取数组中的第一个元素1
int i = arr[0];
System.out.println(i);
int [] arr2 = new int[2];
//给arr2数组中第一个元素赋值
arr2[0] = 6;
//输出arr2数组中的第一个元素
System.out.println(arr2[0]);
//如果指定索引小于0或者大于等于数组的长度时,编译时不会出现异常,在运行是会出现运行时异常.
//异常java.lang.ArrayIndexOutOfBoundsException: 2(数组索引越界异常)
System.out.println(arr2[2]);
//数组提供了length属性,通过这个属性可以访问数组的长度,获取数组长度后可以遍历数组中的每个元素.
//获取arr数组的长度
int length = arr.length;
for (int j = 0; j < length; j++) {
System.out.println(arr[j]);
}
//在jdk1.5提供了foreach循环,不需要知道数组的长度
for (int k : arr) {
System.out.println(k);
}
4. 深入数组:
数组是一种引用数据类型,数组引用变量只是一个引用,数组元素和数组变量在内存中是分开存放的.
1.内存中的数组:
数组引用变量只是一个引用,这个引用变量可以指向任何有效的内存,只有当该引用指向有效内存后,才可通过该数组变量来访问数组元素,引用变量是访问真实对象的根本方式,也就是说,如果我们要在程序中访问数组,只能通过这个数组的引用变量来访问.
数组元素存储在堆内存中,数组引用变量被存储在栈内存中.
数组存储内存图如下:
如果需要访问数组元素,只能通过arr[index]的方式,数组引用变量是访问数组元素的唯一方式.
如果堆内存中的数组不再有任何的变量指向自己,那么这个数组就会称为垃圾,会被垃圾回收机制回收.
2.基本类型数组的初始化:
//定义名称为arr的数组
int[] arr;
//arr数组初始化,定义长度
arr = new int[3];
//for循环为数组赋值
for (int i = 0; i < arr.length; i++) {
arr[i] = i+1;
}
上面代码是基本数据类型数组的初始化的典型过程.
执行int[] arr时,内存示意图:
执行arr = new int[3];时,内存示意图:
执行循环为数组元素赋值时,内存示意图:
3.引用类型数组的初始化:
引用类型数组的数组元素是引用,指向的是另一块内存.这块内存存储的是有效数据.
public class User{
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 身高
*/
private Double height;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Double getHeight() {
return height;
}
public void setHeight(Double height) {
this.height = height;
}
public User() {
}
public User(String name, Integer age, Double height) {
this.name = name;
this.age = age;
this.height = height;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", height=" + height +
'}';
}
}
public static void main(String[] args) {
//定义名称为users的数组,类型为User
User[] users;
//执行动态初始化
users = new User[2];
//创建第一个User实例
User user = new User();
user.setName("张三");
user.setAge(29);
user.setHeight(178.2);
//创建第二个User实例
User user1 = new User();
user1.setName("李四");
user1.setAge(25);
user1.setHeight(182.2);
//将user赋值给users数组的第一个元素
users[0] = user;
//将user1赋值给users数组的第二个元素
users[1] = user1;
//以后输出结果一致,因为user和users[0]指向的是同一个User实例
System.out.println(user.toString());
System.out.println(users[0].toString());
}
执行User[] users;时,内存示意图:
执行users = new User[2];时,内存示意图:
创建两个User实例时,内存示意图:
将user和user1赋值给数组元素时,内存示意图:
图中可以看出,user和users[0]指向同一个内存区域,都是引用类型变量.
若有错误和补充欢迎指出
网友评论