dataType[] arrayRefVar;
(推荐的方式)dataType arrayRefVar[];
**Tip:建议使用 dataType[] arrayRefVar 的声明风格声明数组变量。 dataType arrayRefVar[] 风格是来自 C/C++ 语言 **
arrayRefVar = new dataType[arraySize];
int[] array1 = new int[]{1, 2, 3};
(静态初始化)int[] array1 = {1, 2, 3};
(类型推断)String[] array2 = new String[3];
(动态初始化,数组的初始化和数组元素的的赋值操作分开进行)array[number]
可以使用下标的方式对数组内部数据进行赋值和读取操作package study1;
public class a {
public static void main(String[] args) {
int[] a = {1, 2, 3, 4, 5};
for(int i : a){
System.out.println(i);
}
}
}
java虚拟机对内存区域的划分
堆(Heap)
方法区(Method Area)
程序计数器(Program Counter Register)
虚拟机栈(JVM Stacks)
虚拟机栈线程私有,生命周期与线程相同。
栈帧(Stack Frame)是用于支持虚拟机进行方法调用和方法执行的数据结构。栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息。每一个方法从调用至执行完成的过程,都对应着一个栈帧在虚拟机栈里从入栈到出栈的过程。
图示解析
局部变量表(Local Variable Table)是一组变量值存储空间,用于存放方法参数和方法内定义的局部变量。包括8种基本数据类型、对象引用(reference类型)和returnAddress类型(指向一条字节码指令的地址)。
其中64位长度的long和double类型的数据会占用2个局部变量空间(Slot),其余的数据类型只占用1个。
如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果虚拟机栈动态扩展时无法申请到足够的内存时会抛出OutOfMemoryError异常。
操作数栈(Operand Stack)也称作操作栈,是一个后入先出栈(LIFO)。随着方法执行和字节码指令的执行,会从局部变量表或对象实例的字段中复制常量或变量写入到操作数栈,再随着计算的进行将栈中元素出栈到局部变量表或者返回给方法调用者,也就是出栈/入栈操作。
动态链接:Java虚拟机栈中,每个栈帧都包含一个指向运行时常量池中该栈所属方法的符号引用,持有这个引用的目的是为了支持方法调用过程中的动态链接(Dynamic Linking)。
方法返回:无论方法是否正常完成,都需要返回到方法被调用的位置,程序才能继续进行。
本地方法栈(Native Method Stacks)
总结
排序算法的优劣
排序算法的分类
冒泡排序
图示
示例代码
package study1;
import java.util.Scanner;
public class a {
public static void main(String[] args) {
int[] array1 = new int[10];
System.out.println("请输入需要排列的十个整数:");
Scanner getNumber = new Scanner(System.in);
for(int i=0; i<10; i++){
array1[i] = getNumber.nextInt();
}
//冒泡排序
for(int i=0; i<10; i++){
for(int j=0; j array1[j+1]){
int temp = array1[j];
array1[j] = array1[j+1];
array1[j+1] = temp;
}
}
}
System.out.println("排序完成!");
for(int i=0; i<10; i++){
System.out.println(array1[i]);
}
}
}
理解:
选择排序
图示
package study1;
public class a {
public static void main(String[] args) {
int[] array = {11, 21, 4, 65, 32, 7};
for(int i=0; i
图示
代码示例
package study1;
public class a {
public static void main(String[] args) {
int[] array = {11, 21, 4, 65, 32, 7};
int current;
for (int i = 0; i < array.length - 1; i++) {
current = array[i + 1]; // 当前排序到的元素
int preIndex = i; // 已经排序完成的最后一个元素的下标
// 将当前排序的元素与每个已完成排序的元素比较
while (preIndex >= 0 && current < array[preIndex]) {
array[preIndex + 1] = array[preIndex];
preIndex--;
}
array[preIndex + 1] = current;
}
for(int j=0; j
理解:
静态初始化:int[][] arr = new int[][]{ {1, 2, 3}, {"a", "b", "c"}};
动态初始化:String[][] arr2 = new String[2][3];
(第二个数组可以暂时不去指定元素个数)
注意:二维数组中的外层元素保存的是地址值(内层数组,数组为引用数据类型),也就是说,若不给二维数组初始化将保存的值为null(引用数据类型的默认值)
杨辉三角
package study1;
public class a {
public static void main(String[] args) {
int[][] array = new int[10][];
for(int i=0; i1){
for(int j=1; j
java.util.Arrays
:操作数组的工具类Arrays.equals(a, b)
比较两个数组是否相同Arrays.toString(a)
以字符串的形式输出数组Arrays.fill(a, value)
将数组中所有的元素替换为指定的值Arrays.sort(b)
将数组排序(快速排序)Arrays.binarySearch(b, 1)
使用二分法查找有序数组(返回值为复数则未找到指定元素)new Phone().function···
示例
public class Dog{
String breed;
int age;
String color;
void barking(){
}
void hungry(){
}
void sleeping(){
}
}
一个类可以包含以下类型变量:
每个类都有构造方法。如果没有显式地为类定义构造方法,Java 编译器将会为该类提供一个默认构造方法。
在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称必须与类同名,一个类可以有多个构造方法。
示例
public class Puppy{
public Puppy(){ // 没有返回值
}
public Puppy(String name){
// 这个构造器仅有一个参数:name
}
}
对象是根据类创建的。在Java中,使用关键字 new 来创建一个新的对象。创建对象需要以下三步:
示例
public class Puppy{
public Puppy(String name){
//这个构造器仅有一个参数:name
System.out.println("小狗的名字是 : " + name );
}
public static void main(String[] args){
// 下面的语句将创建一个Puppy对象
Puppy myPuppy = new Puppy( "tommy" );
}
}
import java.util.*;
由static修饰的变量称为静态变量,其实质上就是一个全局变量。如果某个内容是被所有对象所共享,那么该内容就应该用静态修饰;没有被静态修饰的内容,其实是属于对象的特殊描述。
不同的对象的实例变量将被分配不同的内存空间, 如果类中的成员变量有类变量,那么所有对象的这个类变量都分配给相同的一处内存,改变其中一个对象的这个类变量会影响其他对象的这个类变量,也就是说对象共享类变量。
成员变量和类变量的区别:
成员变量随着对象的创建而存在,随着对象的回收而释放。
静态变量随着类的加载而存在,随着类的消失而消失。
成员变量只能被对象调用。
静态变量可以被对象调用,还可以被类名调用。
成员变量也称为实例变量。
静态变量也称为类变量。
成员变量存储在堆内存的对象中,所以也叫对象的特有数据。
静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据
static关键字
static 关键字,是一个修饰符,用于修饰成员(成员变量和成员函数)。
1、想要实现对象中的共性数据的对象共享。可以将这个数据进行静态修饰。
2、被静态修饰的成员,可以直接被类名所调用。也就是说,静态的成员多了一种调用方式。类名.静态方式。
3、静态随着类的加载而加载。而且优先于对象存在。
注意
1、有些数据是对象特有的数据,是不可以被静态修饰的。因为那样的话,特有数据会变成对象的共享数据。这样对事物的描述就出了问题。所以,在定义静态时,必须要明确,这个数据是否是被对象所共享的。
2、静态方法只能访问静态成员,不可以访问非静态成员。因为静态方法加载时,优先于对象存在,所以没有办法访问对象中的成员。
3、静态方法中不能使用this,super关键字。因为this代表对象,而静态在时,有可能没有对象,所以this无法使用
是否真的需要静态成员
1、成员变量。(数据共享时静态化)
该成员变量的数据是否是所有对象都一样:
如果是,那么该变量需要被静态修饰,因为是共享的数据。
如果不是,那么就说这是对象的特有数据,要存储到对象中。
2、成员函数。(方法中没有调用特有数据时就定义成静态)
如果判断成员函数是否需要被静态修饰呢?
只要参考,该函数内是否访问了对象中的特有数据:
如果有访问特有数据,那方法不能被静态修饰。
如果没有访问过特有数据,那么这个方法需要被静态修饰。
成员变量和静态变量的区别:
1、成员变量所属于对象。所以也称为实例变量。
静态变量所属于类。所以也称为类变量。
2、成员变量存在于堆内存中。
静态变量存在于方法区中。
3、成员变量随着对象创建而存在。随着对象被回收而消失。
静态变量随着类的加载而存在。随着类的消失而消失。
4、成员变量只能被对象所调用 。
静态变量可以被对象调用,也可以被类名调用。
所以,成员变量可以称为对象的特有数据,静态变量称为对象的共享数据。
1、构造方法的名字和类名相同,并且没有返回值。
2、构造方法主要用于为类的对象定义初始化状态。
3、我们不能直接调用构造方法,必须通过new关键字来自动调用,从而创建类的实例。
4、Java的类都要求有构造方法,如果没有定义构造方法,Java编译器会为我们提供一个缺省的构造方法,也就是不带参数的构造方法。
new关键字的作用
1、为对象分配内存空间。
2、引起对象构造方法的调用。
3、为对象返回一个引用。
命名规则
语法示例
修饰符 返回值类型 方法名(参数类型 参数名){ ... 方法体 ... return 返回值; }
修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
返回值类型 :方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void。
方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
方法体:方法体包含具体的语句,定义该方法的功能。
可变参数
可变参数的声明: typeName... parameterName
注意!区分值传递和引用传递
示例
package study1;
public class a {
public static void main(String[] args) {
fun(1, 22, 31, 2, 44, 21, 98);
fun(new int[]{1, 22, 31, 2, 44, 21, 98});
}
public static void fun(int... numbers){
if (numbers.length == 0) {
System.out.println("No argument passed");
return;
}
int result = numbers[0];
for (int i = 1; i < numbers.length; i++){
if (numbers[i] > result) {
result = numbers[i];
}
}
System.out.println("The max value is " + result);
}
}
finalize
方法
Java 允许定义这样的方法,它在对象被垃圾收集器析构(回收)之前调用,这个方法叫做 finalize( ),它用来清除回收对象。
在 finalize() 方法里,你必须指定在对象销毁时候要执行的操作。
当然,Java 的内存回收可以由 JVM 来自动完成。如果你手动使用,则可以使用上面的方法。
该函数的一般格式
protected void finalize() // 关键字 protected 是一个限定符,它确保 finalize() 方法不会被该类以外的代码调用。 { // 在这里终结代码 }
int larger = max(30, 40);
System.out.println("Hello Java");
Tip:注意!在一些其它语言中方法指过程和函数。一个返回非void类型返回值的方法称为函数;一个返回void类型返回值的方法叫做过程。
一个方法在内部调用自身称为递归调用
方法的递归包含了一种隐式的循环,他会重复指定某段代码,但是这种循环执行无需循环的控制
递归一定要已知方向递归(临界条件),否则将会称为无穷递归(类似与死循环)
简单示例
// 递归求和 public static int fun(int x){ if(x == 1){ return 1; }else{ return x + fun(x - 1); } }
变量的范围是程序中该变量可以被引用的部分。
方法内定义的变量被称为局部变量。
局部变量的作用范围从声明开始,直到包含它的块结束。
局部变量必须声明才可以使用。
方法的参数范围涵盖整个方法。参数实际上是一个局部变量。
for循环的初始化部分声明的变量,其作用范围在整个循环。
但循环体内声明的变量其适用范围是从它声明到循环体结束。它包含如下所示的变量声明:
你可以在一个方法里,不同的非嵌套块中多次声明一个具有相同的名称局部变量,但你不能在嵌套块内两次声明局部变量。
Tip:命令行参数是在执行程序时候紧跟在程序名字后面的信息。