@nextleaf
2018-08-08T10:13:14.000000Z
字数 5509
阅读 663
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(){
//默认值为0
System.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){
//这个构造器仅有一个参数:name
System.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 还贷款