@nextleaf
2018-08-08T02:13:14.000000Z
字数 5509
阅读 800
Java 工作日志 函数 面向对象 内存
纸作业(x2):
出租车
圣诞树
九九乘法表
数组 遍历,排序
函数 实参形参
Java内存 堆、栈、常量池
public static void main(String[] args) {//静态初始化int array[]={1,-1,2,-2,3,-3,4,-4,5,-6,7,-8,-9,10};System.out.println(array.length);for (int i : array) {System.out.print(i+"\t");}}
遍历:
for (int i : array) {System.out.print(i+"\t");}
排序:
public void sort() {//不重复的随机数组int array[]=NumberUtil.generateRandomNumber(-18,18,30);System.out.print("初始:");Console.log(array);//升序System.out.print("升序(默认):");Arrays.sort(array);Console.log(array);//降序System.out.print("降序:");Console.log(descendingSort(array));}//降序方法public int[] descendingSort(int[] array) {/*int array2[] = array.clone();//浅复制*///int copy[] = new int[array.length];//System.arraycopy(array, 0, copy, 0, array.length);int[] copy = Arrays.copyOf(array, array.length);int k=0;for (int i = array.length-1; i >=0 ; i--) {copy[k++] = array[i];}return copy;}
形参,函数定义处
实参,函数调用处
函数调用的本质是实参把自己的副本复制给形参
public static void main(String[] args) {swap(-1,2);}//交换值public static void swap(int a,int b) {a=a+b;b=a-b;a=a-b;Console.log(a+","+b);}
内存中的位置
成员变量:在堆中(方法区中的静态区)
局部变量:在栈中
生命周期
成员变量:随着对象的创建而存在,随着对象的消失而消失
局部变量:随着方法的调用或者代码块的执行而存在,随着方法的调用完毕或者代码块的执行完毕而消失
成员变量:有默认初始值
局部变量:没有默认初始值,使用之前需要赋值,否则编译器会报错
Java的堆是一个运行时数据区,类的(对象从中分配空间。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,缺点是存取速度较慢
栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的
对于栈和常量池中的对象可以共享,对于堆中的对象不可以共享。
对于字符串,其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才能确定的就存储在堆中。对于equals相等的字符串,在常量池中永远只有一份,在堆中有多份。
在函数中定义的一些基本类型的变量数据和对象的引用变量都在函数的栈内存中分配(对象本身存放在堆中)。当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当该变量退出该作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用.
堆内存用来存放由new创建的对象和数组。 在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。
常量池指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。除了包含代码中所定义的各种基本类型(如int、long等等)和对象型(如String及数组)的常量值(final)还包含一些以文本形式出现的符号引用,比如:
方法和名称和描述符。
虚拟机必须为每个被装载的类型维护一个常量池。常量池就是该类型所用到常量的一个有序集和,包括直接常量(string,integer和 floating point常量)和对其他类型,字段和方法的符号引用。
对于String常量,它的值是在常量池中的。而JVM中的常量池在内存当中是以表的形式存在的, 对于String类型,有一张固定长度的CONSTANT_String_info表用来存储文字字符串值,注意:该表只存储文字字符串值,不存储符号引 用。说到这里,对常量池中的字符串值的存储位置应该有一个比较明了的理解了。
在程序执行的时候,常量池会储存在Method Area,而不是堆中。
结论:
对于
基础类型的变量和常量,变量和引用存储在栈中,常量存储在常量池中。
对于成员变量和局部变量:成员变量就是方法外部,类的内部定义的变量;局部变量就是方法或语句块内部定义的变量。局部变量必须初始化。 形式参数是局部变量,局部变量的数据存在于栈内存中。栈内存中的局部变量随着方法的消失而消失。 成员变量存储在堆中的对象里面,由垃圾回收器负责回收。
面向对象 对象类的概念,类的组成、构造方法、引用、方法重载等知识点
java支持以下基本概念:
对象是类的一个实例,有状态和行为。
类是一个模板,它描述一类对象的行为和状态。
java类可以看成是创建Java对象的模板。
类的基本结构
属性:对象数据的描述
方法:对象的行为
构造方法:用于实例化对象
一个类可以包含以下类型变量:
局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
类变量:类变量也声明在类中,方法体之外,但必须声明为static类型。
一个类可以拥有多个方法
...
每个类都有构造方法。如果没有显式地为类定义构造方法,Java编译器将会为该类提供一个默认构造方法。
在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称必须与类同名,一个类可以有多个构造方法。
1.先执行内部静态对象(类变量)的构造方法
2.再调用父类的构造方法(父类还有父类的话,从最开始的基类开始调用)
3.按声明顺序将成员对象初始化
4.最后调用自身的构造方法
下面是构造方法一个示例:
package com.nl.test;/*构造方法的执行顺序*/class Animal{String name;Animal() {System.out.println("class Animal");}Animal(String name){//子类构造方法中,使用super("Tom");来调用该构造方法。this.name = name;System.out.print(name + " class Animal (custom name)--");printNumber();}public void printNumber(){System.out.println("父类printNumber()");//为什么没有被执行}}class Fish extends Animal{Fish() {System.out.println("class Fish extends Animal");}}class GoldFish extends Fish {GoldFish() {System.out.println("class GoldFish extends Fish");}}class Cat {Cat(){System.out.println("class cat");}}class Rabbit {private static int number;private static Cat cat = new Cat();public Rabbit() {number++;System.out.println(number + "class rabbit");}}class Dog extends Animal{public int dogNumber;private GoldFish goldFish = new GoldFish();//成员对象(引用变量)static Rabbit blackRabbit = new Rabbit();static Rabbit whiterabbit = new Rabbit();public Dog() {super("Tom");//这里调用指定的父类构造方法,若没有指定,则调用默认构造方法System.out.println("class Dog extends Animal");dogNumber = 10;printNumber();}public void printNumber(){//默认值为0System.out.println("子类printNumber():" + dogNumber);}}public class TestInheritanceConstructor{public static void main(String[] args){new Dog();/*构造方法的执行顺序* 1.先执行内部静态对象(blackRabbit)的构造方法,又Rabbit中有静态对象cat,故先执行System.out.println("class cat");* 由于静态对象cat已经被加载过,故在加载内部静态对象whiterabbit的时候,不再加载静态对象cat* 2.再调用父类的构造方法(父类还有父类的话,从最开始的基类开始调用)* 3.按声明顺序将成员对象初始化* 4.最后调用自身的构造方法* */}}
运行结果:
class cat
1class rabbit
2class rabbit
Tom class Animal (custom name)--子类printNumber():0
class Animal
class Fish extends Animal
class GoldFish extends Fish
class Dog extends Animal
子类printNumber():10
在Java中,使用关键字new来创建一个新的对象。创建对象需要以下三步:
例子:
public class Puppy{public Puppy(String name){//这个构造器仅有一个参数:nameSystem.out.println("小狗的名字是 : " + name );}public static void main(String []args){// 下面的语句将创建一个Puppy对象Puppy myPuppy = new Puppy( "tommy" );}}
对象的别名;Java数据类型分两大类:
1.内置数据类型
2.引用数据类型
Site site = new Site("Runoob")
空指针异常:引用指向未知空间(null)。
类内,方法拥有相同的名字,但是有不同的参数列表。
方法重载与修饰符或者返回类型无关,与参数列表参数的顺序、类型、个数有关
//方法重载,方法名一样,不同的参数列表,与修饰符或者返回类型无关public void name1(int a,int b,int c,String d) {System.out.println();}public void name1(int a,int b,String d,int c) {System.out.println("参数顺序不同");}public void name1(int a,int b,double c,String d) {System.out.println("参数类型不同");}public void name1(int b,int c,String d) {System.out.println("参数个数不同");}//只要是方法名一样,参数的顺序和类型不完全一样即可构成重载。
e
e
07:00 - 17:00 还贷款
07:00 - 17:00 还贷款
