数组的创建
public class FirstClass {
//main方法 应用程序的入口
public static void main(String[] args) {
int[] arr1;
//空数组
int[] arr2 = {};
int arr3[] = {};
int[] arr4 = new int[] {1,2,3,4};
int[] arr5 = {1,2,3,4};
//指定数组的长度
int[] arr6 = new int[4];
}
}
- 在Java中,字符数组 != 字符串;
数组的内存
- Java的数组属于引用类型;
- 数组元素存在在堆空间;
- Java的堆内存申请会
自动进行初始化
;
public class FirstClass {
//main方法 应用程序的入口
public static void main(String[] args) {
int[] array = new int[] {1,2,3};
System.out.println(array);
}
}
数组的遍历
import java.util.Iterator;
public class FirstClass {
//main方法 应用程序的入口
public static void main(String[] args) {
int[] array = new int[] {1,2,3};
System.out.println(array);
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
for (int i : array) {
System.out.println(i);
}
}
}
方法
- Java中的方法,就是其他编程语言中的函数function;
- 方法的书写格式
修饰符 返回值类型 方法名(参数列表) {
实现体
}
可变参数
import java.util.Iterator;
public class FirstClass {
//main方法 应用程序的入口
public static void main(String[] args) {
System.out.println(sum(10,20,30,40));
}
public static int sum(int... numbers) {
System.out.println(numbers.length);
int result = 0;
for (int i : numbers) {
result += i;
}
return result;
}
}
- 其中sum函数的参数numbers为可变参数,最终会转成数组;
- 可变参数,必须是最后一个参数;
参数传递
- 基本数据类型作为参数是值传递;
- 引用类型作为参数是引用传递,也就是地址传递;
import java.util.Iterator;
public class FirstClass {
//main方法 应用程序的入口
public static void main(String[] args) {
int m = 100;
test(m);
System.out.println(m);
//数组k的首元素 变成了44
int[] k = {10,20,30};
test1(k);
System.out.println(k[0]);
}
public static void test(int a) {
a = 10;
}
public static void test1(int[] a) {
a[0] = 44;
}
}
方法签名
- 方法签名:有方法名与参数类型两部分组成;
public static void test(int a) {
a = 10;
}
public static int sum(int a,int b) {
return a + b;
}
- 方法签名为:
test(int)
和sum(int ,int)
,相当于方法类型; - 在同一个类中,不能定义方法签名相同的方法;
方法的重载
- Java的方法支持重载,方法名相同,参数类型不同;
public static int sum(int a,int b) {
return a + b;
}
public static double sum(double a,double b) {
return a + b;
}
public static float sum(Float a,Float b) {
return a + b;
}
- 上述三个方法,构成方法重载;
栈帧
- 栈帧对着方法的调用而创建,随着
方法结束而销毁
,存储了方法的局部变量信息;
import java.util.Iterator;
public class FirstClass {
//main方法 应用程序的入口
public static void main(String[] args) {
sum(4);
}
public static int sum(int a) {
if (a <= 1) return a;
return a + sum(a-1);
}
}
-
栈帧如下所示:
类的定义,对象的创建
- 在Java中,所有对象都是new出来的,所有对象的内存都是在堆空间,所有保存对象的变量都是引用类型;
- Java运行时环境有个垃圾回收机制,简称GC,会自动回收不再使用的内存;
- 当一个对象没有任何引用指向时,会被GC回收掉内存;
简单对象的内存布局
- 首先定义一个类class Dog,如下:
public class Dog {
public int age;
public double price;
public void run() {
System.out.println("run");
}
public void eat(String what) {
System.out.println("eat:" + what);
}
}
- 在main函数中初始化Dog对象,代码如下:
public class main {
public static void main(String[] args) {
System.out.println("面向对象 main");
Dog dog = new Dog();
dog.age = 20;
dog.price = 1000.0;
dog.run();
dog.eat("apple");
}
}
-
dog对象在内存中布局,如下所示:
复杂对象的内存布局
- 在定义一个Person类,如下:
public class Person {
public int age;
public Dog dog;
}
- 在main函数中,调用如下:
public class main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.price = 1000.0;
Person person = new Person();
person.age = 22;
person.dog = dog;
}
}
- 内存布局如下:
数组存储对象数据的内存布局
public class main {
public static void main(String[] args) {
Dog[] dogs = new Dog[7];
for (int i = 0; i < dogs.length; i++) {
dogs[i] = new Dog();
}
}
}
Java程序的内存划分
- Java虚拟机在执行Java程序时会将内存划分为若干不同的数据区域,主要有如下:
-
PC寄存器
:存储Java虚拟机正在执行的字节码指令的地址; -
Java虚拟机栈
:存储栈帧; -
堆
:存储GC所管理的各种对象; -
方法区
:存储每一个类的结构信息,比如字段和方法信息,构造方法和普通方法; -
本地方法栈
:用来支持native方法的调用,比如C语言编写的方法;
-
对象方法的存储位置
- 根据Java程序的内存划分,可以知道
对象方法存储在方法区
;
构造方法
- 构造方法,也叫构造器,能够更方便的创建一个对象;
- 方法名必须与类名相同;
- 没有返回值类型;
- 可以重载;
- 案例代码:
public class Dog {
public int age;
public double price;
public Dog() {
}
public Dog(int age) {
this.age = age;
}
public Dog(int age,double price) {
this.age = age;
this.price = price;
}
}
- 三个构造方法,支持方法重载;
- 调用入下:
public class main {
public static void main(String[] args) {
Dog dog1 = new Dog();
Dog dog2 = new Dog(22);
Dog dog3 = new Dog(22, 110.0);
}
}
this指针
- this是一个指向当前对象的引用,常见用途有:
- 访问当前类中定义的成员变量;
- 调用当前类中定义的方法(包括构造方法);
- this的本质是一个隐藏的,位置最靠前的方法参数;
- 构造方法中使用this 调用其他构造方法;
- 如果在构造方法中调用了其他构造方法,构造方法调用语句必须是构造方法中第一条语句;
- 案例代码如下:
public class Cat {
public String name;
public int age;
public double price;
public Cat(String name,int age,double price) {
this.name = name;
this.age = age;
this.price = price;
}
//this 调用上面三参数的构造方法
public Cat(String name) {
this(name, 0, 0);
}
public void run() {
}
public void eat() {
this.run();
}
}
- 当new一个Cat对象,然后调用run方法,虽然run方法没有参数,但是底层会将当前对象也就是this,作为隐藏参数传递给run方法;
默认构造方法
- 如果一个类没有自定义构造方法,编译器会自动为它提供一个无参数的默认构造方法;
- 一旦自定义了构造方法,默认构造方法就不再存在了;
包(Package)
- Java中的包就是其他编程语言中的命名空间,包的本质就是文件夹,常见作用有:
- 将不同的类进行组织管理,访问控制;
- 解决命名冲突;