java类静态域、块,非静态域、块,构造函数的初始化顺序
java里面main函数为什么要用static修饰

java⾥⾯main函数为什么要⽤static修饰
这学期刚开java,因为之前只写过C++和Python没接触过java,有些写法挺不习惯的,今天写完⼀个程序,run的时候发现提⽰the selection can't be launched.......查了⽹上⼀些资料,虽然不知道具体是不是我以为的这个原因,我main函数没有写static(C++和Python都没这玩意⼉),我想我这⾥应该是这个原因。
如果不是这个原因,欢迎指正。
那么我那时候就在想,为什么我不加static就这样了,于是去查了查static的作⽤:
static 是静态的意思,这个我们在学C和C++⾥⾯就学过。
0.static 修饰的域,我们叫静态域,它是归类所有的,被所有对象所共享,只有⼀个
1.static修饰的区块,域只会初始化⼀次
2.static修饰的域或⽅法,可以直接通过类的名字加上.进⾏调⽤
3.static修饰的⽅法内不能直接使⽤⾮静态成员
static这个字告诉编译器,这个main函数是静态的,储存在静态存储区,在定义以后它就存在了,缺少它的话,编译并不会出错,⽽是在运⾏的时候报错,因为这个时候main这个类并没有实例化,⾃然main⽅法就不能⽤,加上static之后,这个⽅法(main)就变成了静态的,不需要实例化就能⽤,我记得刚开始学C语⾔的时候,我们⽼师说main是⼀个程序的⼊⼝,当时怎么想都没想明⽩,现在看这个例⼦,就可以想得通为什么要加static,main作为⼊⼝,不可能先去实例化⼀个对象去调⽤它,所以他必须可以直接调⽤。
java数组初始化方法

java数组初始化方法Java是一种面向对象的编程语言,广泛应用于各个领域。
在Java 中,数组是一种常用的数据结构,用于存储一组相同类型的数据。
数组的初始化是指在创建数组时,为数组元素赋予初始值的过程。
本文将介绍Java中数组的初始化方法。
1. 静态初始化:静态初始化是指在创建数组的同时为数组元素赋予初始值。
可以使用大括号{}来初始化数组,大括号中的值按照数组元素的顺序依次赋值。
例如:```int[] numbers = {1, 2, 3, 4, 5};```这样就创建了一个包含5个整数的数组,初始值分别为1、2、3、4、5。
2. 动态初始化:动态初始化是指在创建数组后,使用循环或逐个赋值的方式为数组元素赋予初始值。
例如:```int[] numbers = new int[5];for (int i = 0; i < numbers.length; i++) {numbers[i] = i + 1;}```这样就创建了一个包含5个整数的数组,初始值分别为1、2、3、4、5。
3. 默认初始化:在Java中,如果没有对数组进行显式初始化,那么数组的元素将会被自动初始化为默认值。
对于整数类型的数组,默认值为0;对于浮点数类型的数组,默认值为0.0;对于布尔类型的数组,默认值为false;对于引用类型的数组,默认值为null。
例如:```int[] numbers = new int[5];System.out.println(numbers[0]); // 输出0```4. 匿名数组初始化:在某些情况下,我们可以直接在方法参数或返回值中使用匿名数组初始化。
例如:```public static void printArray(int[] array) {for (int i = 0; i < array.length; i++) {System.out.println(array[i]);}}printArray(new int[]{1, 2, 3, 4, 5});```这样就创建了一个匿名数组,并将其作为参数传递给printArray方法。
static的特性

static的特性1,static⽅法就是没有this的⽅法。
在static⽅法内部不能调⽤⾮静态⽅法,反过来是可以的。
⽽且可以在没有创建任何对象的前提下,仅仅通过类本⾝来调⽤static⽅法。
这实际上正是static⽅法的主要⽤途。
(简⽽⾔之)⽅便在没有创建对象的情况下来进⾏调⽤(⽅法/变量)。
2,static⽅法 static⽅法⼀般称作静态⽅法,由于静态⽅法不依赖于任何对象就可以进⾏访问,因此对于静态⽅法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。
3,static变量 static变量也称作静态变量,静态变量和⾮静态变量的区别是:静态变量被所有的对象所共享,在内存中只有⼀个副本,它当且仅当在类初次加载时会被初始化。
4,static代码块 static关键字还有⼀个⽐较关键的作⽤就是⽤来形成静态代码块以优化程序性能。
static块可以置于类中的任何地⽅(除了⽅法内部),类中可以有多个static块。
在类初次被加载的时候,会按照static块的顺序来执⾏每个static块,并且只会执⾏⼀次。
静态块外部不能直接调⽤,静态块⼀般⽤在⼀些初始化操作。
static容易误解的地⽅:1,Java中的static关键字不会影响到变量或者⽅法的作⽤域。
在Java中能够影响到访问权限的只有private、public、protected(包括包访问权限)这⼏个关键字。
2,静态成员变量虽然独⽴于对象,但是不代表不可以通过对象去访问,所有的静态⽅法和静态变量都可以通过对象访问(只要访问权限⾜够)。
3,Java中切记:static是不允许⽤来修饰局部变量。
(java语法规定的)构造器是不是静态的?不是1,静态⽅法中不能使⽤this,⽽构造器中可以使⽤this关键字。
this是指调⽤当前⽅法的对象,⽽静态⽅法不属于任何对象。
2,静态⽅法是独⽴于对象的类级别的⽅法。
不创建实例的调⽤也不需要实例,构造函数是由jvm创建类实例时⾃动调⽤3,构造⽅法不能继承,⽽静态⽅法可以继承。
JAVA基础知识重难点

JAVA基础知识重难点声明:以下内容为个⼈期末对JAVA基础知识的总结,来源于各种资料搜索和个⼈理解整理⽽出,也许有不妥的地⽅,欢迎学习指教1.Java语⾔具有可移植性、可跨平台运⾏特点的原因是什么?Java——编译器——jvm——平台Java⽤编译器编译成.class的字节码⽂件,字节码类似于机器指令,同⼀字节码可以在任何带jvm虚拟机的平台运⾏,从⽽实现java的跨平台性。
所谓语⾔的跨平台性并不是说是源⽂件的跨平台性(如果要这么定义那么任何的语⾔都是跨平台性的),⽽是指源⽂件编译⽣成的⽂件的跨平台性。
因为Java字节码是结构中⽴的,所以Java 的程序是可移植的。
他们可以不经过重新编译⽽在任何⼀个机器上运⾏。
2.为什么说Java语⾔具有健壮、安全的特性?Java 编译器检测出许多别的语⾔只有在⾸次执⾏的时候才会指出的问题。
Java 已经清除了⼏种在其它语⾔中被发现易于出错的编程结构。
Java具有运⾏时异常处理特性,垃圾回收机制,它为健壮性提供了编程⽀持。
Java 实现了⼏种安全机制以保护你的系统遭受危险程序的破坏。
3.简述Java虚拟机(JVM)的作⽤是什么?JVM就是Java虚拟机,它是⼀个虚构出来的计算机,可在实际的计算机上模拟各种计算机的功能。
JVM有⾃⼰完善的硬件结构,例如处理器、堆栈和寄存器等,还具有相应的指令系统。
JVM是java字节码执⾏的引擎,还能优化java字节码,使之转化成效率更⾼的机器指令。
Java程序的跨平台特性主要就是因为JVM 实现的。
在编译java程序时会将写好的源程序通过编译器编译⽣成.class⽂件(⼜称为字节码⽂件),不同的平台对应着不同的JVM,之后就是通过JVM内部的解释器将字节码⽂件解释成为具体平台上的机器指令执⾏,所以就可以实现java程序的跨平台特性。
4.简述JVM的垃圾回收机制。
确保被引⽤对象的内存不被错误的回收。
当⼀个对象不再有任何⼀个引⽤变量指向它时,这个对象就被应⽤抛弃。
Java中static静态变量的初始化完全解析

Java中static静态变量的初始化完全解析静态变量初始化顺序1.简单规则⾸先先看⼀段最普遍的JAVA代码:123 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21public class Test{public static Test1 t = new Test1(); public static int a = 0;public static int b;public static void main(String[] arg) {System.out.println(Test.a);System.out.println(Test.b);}}class Test1{public Test1(){Test.a++;Test.b++;}}这⾥先猜下控制台输出结果是什么?OK, 或许你已经猜到下⾯了结果了,那么你还是熟悉Java的。
复制代码代码如下:0 1如果你不明⽩是为什么会输出上⾯的结果,那么我来告诉你。
Java静态变量初始化遵循以下规则:静态变量会按照声明的顺序先依次声明并设置为该类型的默认值,但不赋值为初始化的值。
声明完毕后,再按声明的顺序依次设置为初始化的值,如果没有初始化的值就跳过。
看了这个就会明⽩,原来Test.a的值变化了三次。
声明时设置为0>>Test1::Test1⾥设置为1>>Test.a初始化为02.复杂规则明⽩了这个,请再看下⾯的代码。
1234567 8 9 10 11 12 13public class A{public static int b = B.a;public static A plus =new A("A");public static final int finalInt = (int)(Math.random()*100); public static B p = new B("A");public static final String finalStr = "finalStr";14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 public static final Integer finalInteger = new Integer(10); public static int a = 1;public static B c = null;public A(String from){System.out.println("----------- begin A::A ----------------");System.out.println("A::A, from="+from);System.out.println("A::A, A.b="+A.b);System.out.println("A::A, A.finalInt="+A.finalInt);System.out.println("A::A, B.a="+B.a);System.out.println("A::A, B.plus="+B.plus);System.out.println("----------- end A::A ----------------");}public static void main(String[] arg){System.out.println("main, A.b="+A.b);System.out.println("main, B.t="+B.t);System.out.println("main, C.a="+C.a);}}class B{public static int t = A.a;public static A plus = new A("B");public static int a = 1;public B(String from){System.out.println("----------- begin B::B ----------------");System.out.println("B::B, from="+from);System.out.println("B::B, B.a="+B.a);System.out.println("B::B, A.a="+A.a);System.out.println("B::B, A.p="+A.p);System.out.println("B::B, A.plus="+A.plus);System.out.println("B::B, A.finalInt="+A.finalInt);System.out.println("B::B, A.finalInteger="+A.finalInteger); System.out.println("B::B, A.finalStr="+A.finalStr);System.out.println("----------- end B::B ----------------");}}class C{public static final A a = new A("C");}这个你还能猜到输出结果吗? 我是在⼀边测试⼀边写的,所以我没猜出来.哈哈控制台输出结果为:1234 5 6 7 8 9 10 11 12 13 14 15----------- begin A::A ----------------A::A, from=BA::A, A.b=0A::A, A.finalInt=0A::A, B.a=0A::A, B.plus=null----------- end A::A --------------------------- begin A::A ----------------A::A, from=AA::A, A.b=1A::A, A.finalInt=0A::A, B.a=1A::A, B.plus=A@a90653----------- end A::A ----------------16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34----------- begin B::B ----------------B::B, from=AB::B, B.a=1B::B, A.a=0B::B, A.p=nullB::B, A.plus=A@1fb8ee3 B::B, A.finalInt=61B::B, A.finalInteger=null B::B, A.finalStr=finalStr----------- end B::B ----------------main, A.b=1main, B.t=0----------- begin A::A ----------------A::A, from=CA::A, A.b=1A::A, A.finalInt=61A::A, B.a=1A::A, B.plus=A@a90653----------- end A::A ----------------main, C.a=A@61de33这个结果你没猜到吧,哈哈.要⼀句⼀句的讲解程序执⾏结果,还是要很到的篇幅的.这⾥就直接写出Java静态变量初始化遵循的规则了。
java编程思想第四版习题答案

java编程思想第四版习题答案【篇一:java编程思想第四版_读书笔记】面向对象程序设计(object-oriented programming oop),uml(unitied modelling language 统一建模语言)。
将对象想像成“服务提供者” ,它们看起来像什么?能够提供哪些服务?需要哪些对象?2.java中动态绑定是默认行为。
java采用动态内存分配方式,通过new操作在堆(heap)的内存池中动态创建对象。
java存储结构类型:1)寄存器2)堆栈,主要存储对象引用3)堆,主要用于存放所有的java对象4)常量存储,也就是程序代码区5)非ram存储,如流对象和持久化对象。
基本类型不用new来创建变量,而且这个变量直接存储”值”,并置于堆栈中。
3.biginteger和bigdecimal的使用。
当变量作为类的成员使用时当变量作为类的成员使用时,java才确保给定其默认初当变量作为类的成员使用时始值,但是在方法中定义的变量,它有可能是任意值。
面向对象的程序设计可以归纳为“向对象发送消息” 。
关键字static。
4.javadoc只能为public和protected成员进行文档注释,但是也可以通过-private进行标记注释。
javadoc常用方法: @see 引用其他类,link package.class#member label}, {@ {@docroot},{@inheritdoc},@version,@ author,@since,@param,@return,@throws,@deprecated。
5.整数除法会直接去掉结果的小数位。
基本类型的对象如果直接对它们赋值,对象指向同一个常量存储区,但是如果通过对象来初始化则会指向不同的堆的存储区。
如:string st1 = new string(a);string st2 = new string(a); st1==st2 false string st1 = a; string st2 = a; st1==st2 true6.逻辑操作符:与()、或(||)、非(!),其中与()、或(||)会产生短路现象。
关于C++之(非)静态成员的相关问题

关于C++之(非)静态成员的相关问题C++中为什么不能在类定义中初始化非静态成员变量,只能在构造函数中初始化?答:首先,类究竟什么?类是一个对事物具体抽象的模型,注意,它仅是一个抽象的、慨念上的东东。
从程序设计层面看,它仅是一个声明,并不代表一个具体的实例,即使它有成员函数的定义,但在内存实例这个层面,它什么也没有!什么都没有,你到那儿去初始化它的成员x呢? 而且,从类的语意来看,它表示有无限个具有相似性(不是相同性)的对象实例的抽象慨括,非静态成员变量对类来说,是一个变化的值(有无穷的解),它是类的可变部份,语言以及类的设计者不能以相同的值去初始化其可变部份(x)!但对类的不变部份,语言还是适当的允许你在类中去初始化,例如整型int及类整型(long、char等)等静态常量你还是可以在类中初始化它们的!定义类的时候并没有分配内存,这时候赋值的话值放在哪里呢? 当用类构造对象的时候首先分配内存然后调用构造函数,这时候才可以初始化非静态成员变量. 静态成员变量定义的时候在静态存储区中就分配了内存所以可以初始化.静态成员变量在C++中(以及其他一些语言,如C#,Java 等面向对象的语言中)类的成员变量被声明为static(称为静态成员变量),意味着它为该类的所有实例所共享,也就是说当某个类的实例修改了该静态成员变量,其修改值为该类的其它所有实例所见。
比如在某个类A中声明一个static int number;初始化为0。
这个number就能被所有A的实例共用。
在A的构造函数里加上number++,在A的析构函数里加上number--。
那么每生成一个A的实例,number就加一,每销毁一个A的实例,number就减一,这样,number 就可以记录程序中共生成了多少个A的实例。
这只是静态成员的一种用法而已。
静态成员函数调用非静态成员变量程序最终都将在内存中执行,变量只有在内存中占有一席之地时才能被访问。
关于静态块、静态属性、构造块、构造方法的执行顺序

关于静态块、静态属性、构造块、构造⽅法的执⾏顺序总结:1、类加载时,执⾏静态代码块和初始化静态变量。
执⾏顺序跟代码顺序⼀致。
2、类实例化时,初始化变量、执⾏代码块、执⾏构造。
其中初始化变量和代码块的顺序跟代码顺序⼀致。
执⾏构造是在最后。
3、实例化⼦类时,会先调⽤⽗类的构造⽅法。
调⽤构造⽅法之前,会先执⾏该类的代码块。
4、类只会加载⼀次。
5、静态变量或静态⽅法中如果调⽤构造,可以把构造当做⼀个普通⽅法来看。
但会先执⾏⼀遍代码块。
下⾯是在⽹上找到的⽐较典型的例⼦,以此来说明例⼀:class A {static {System.out.println("A的静态块");}private static String staticStr = getStaticStr();private String str = getStr();{System.out.println("A的实例块");}public A() {System.out.println("A的构造⽅法");}private static String getStaticStr() {System.out.println("A的静态属性初始化");return null;}private String getStr() {System.out.println("A的实例属性初始化");return null;}public static void main(String[] args) {new B();new B();}}class B extends A{private static String staticStr = getStaticStr();static {System.out.println("B的静态块");}{System.out.println("B的实例块");}public B() {System.out.println("B的构造⽅法");} private String str = getStr();private static String getStaticStr() {System.out.println("B的静态属性初始化");return null;}private String getStr() {System.out.println("B的实例属性初始化");return null;}}该段代码的执⾏结果为:A的静态块A的静态属性初始化B的静态属性初始化B的静态块A的实例属性初始化A的实例块A的构造⽅法B的实例块B的实例属性初始化B的构造⽅法A的实例属性初始化A的实例块A的构造⽅法B的实例块B的实例属性初始化B的构造⽅法由此可见,实例化⼦类的时候,若此类未被加载过,⾸先加载是⽗类的类对象,然后加载⼦类的类对象,接着实例化⽗类,最后实例化⼦类,若此类被加载过,不再加载⽗类和⼦类的类对象。
JAVA语言基础(一)

5
对象初始化
默认的构造函数 如果你没有定义默认的构造函数,那么编译的时候就生成一个默认的 构造函数,并且默认调用父类的默认的构造函数。
类的属性会有默认的初始化值,而局部变量是没有的。 对象是如何初始化顺序 (1)从父类到子类的静态变量和静态代码块依次被初始化。 (2)父类的非静态变量和非静态代码库依次被初始化,接着执行父亲 的构造函数。 (3)子类的非静态变量和非静态代码库依次被初始化,接着执行子类的 构造函数。
如何改写
1.使用==操作符检查“实参是否为指向对象的一个引用”。
2.使用instanceof操作符检查“实参是否为正确的类型”。 3.把参数转换到正确的类型。 4.对于该类中每一个“关键”域,检查实参中的域与当前对象中对应 的域值是否匹配。
9
equals()方法的改写(四)
告诫:
1.当你改写equals的时候,总要改写hashcode。
异常处理基本原则
对于可恢复的条件使用检查异常,对于程序错误使用运行时异常。
思考,讨论 对于用户登录的业务,设计上是否可以考虑使用异常来处理,如果可 以的话该如何设计?
14
异常处理(二)
在return中使用finally
public class MultipleReturns{ public static void f(int i){
JAVA语言探索(一)语言细节
综合软件开发三部 陈华海
Email:hhchen@
JAVA优点(一)
JAVA在需要的地方提供了更多的结构,例如:接口
JAVA减少指针的必要性,让软件更稳定,更好阅读 垃圾收集更容易,因为JAVA自动处理不用的内存
深入理解OOP-java版本

深⼊理解OOP-java版本在我看来,⾯向对象程序设计,不应该拘泥于具体到语⾔层⾯的继承规则,⽽应该单纯的去分析OOP的概念。
每种语⾔对于OOP的理念,都有不同的处理,具体到继承,具体到访问控制。
以⽬前⽽⾔相对经典的两种OOP语⾔C++和java来讲,它们在⾯向对象的问题上,如果在你眼⾥是相去甚远的,只能说你对⾯向对象的理解还是停留在具体的语法和语义上。
⾯向对象程序设计(OOP)的精髓在于:对象驱动,向上转型,后期绑定。
所谓⾯向对象,是对具体业务的层层抽象,形成概念,以概念为核⼼,增加对外接⼝,以接⼝为通道,联系业务。
⾯向对象的理念和⾯向过程的理念的区别是,后者认为程序是⼀系列动作的集合,⽽前者认为程序是⼀系列业务的集合。
java提供了基本类型的包装类,在java中,所有的事物都是对象或者对象的⼀部分。
并且,所有的类都直接或者间接地继承⾃Object,Object是⼀个根类。
这也是java彻底的对向驱动的根据。
相对于⾯向过程的程序设计,⾯向对象更安全,更容易设定访问权限的边界。
java⽤于指定权限边界的关键字有三个public private 和protected。
public是最⼴泛的访问权限,允许⽆条件的访问对应的域和⽅法;private 是最严格的访问权限,只允许当前类中对该域和⽅法的访问;protect是⼀种折衷的选择,允许当前类和被继承之后的类对当前域和⽅法的访问。
除此之外,还有⼀种缺省的访问权限,即不使⽤任何关键字指定访问权限级别,这个时候是包访问权限。
然⽽,在很多时候,理解访问权限不能只根据public、private和protected关键字,很多缺省的权限也许更重要。
对于普通类⽽⾔,只存在两种访问权限,缺省的包访问权限和public访问权限。
这是很容易理解的,如果是protected或者private,以为这类是不可被外界访问的,⽽这个类⾃然失去了存在的意义。
只有⼀种情况下是例外,那就是类属于内部类,这个时候因为有了相应的外部类包装,从⽽可以有对应的继承机制,可以有相应的private 和protected权限控制。
java初始化数组的方法

java初始化数组的方法在Java编程语言中,有多种方法可以初始化数组。
下面介绍几种常用的初始化数组的方式。
1. 直接赋值法:可以在声明数组的同时为数组元素赋值。
例如,我们想要创建一个长度为5的整型数组,并赋予初始值,可以使用以下代码:```javaint[] array = {1, 2, 3, 4, 5};```这样就创建了一个包含5个元素的整型数组,并分别赋值为1、2、3、4和5。
2. 动态初始化法:可以先声明数组,再为数组元素赋值。
例如,我们想要创建一个长度为3的字符串数组,可以使用以下代码:```javaString[] array = new String[3];array[0] = "Java";array[1] = "is";array[2] = "awesome";```这样就创建了一个包含3个元素的字符串数组,并分别赋值为"Java"、"is"和"awesome"。
3. 使用Arrays类的fill()方法:Arrays类是Java提供的一个实用工具类,其中的fill()方法可以用于将指定的值赋给数组的所有元素。
例如,我们想要创建一个长度为4的浮点型数组,并将所有元素都初始化为3.14,可以使用以下代码: ```javafloat[] array = new float[4];Arrays.fill(array, 3.14f);```这样就创建了一个包含4个元素的浮点型数组,并将所有元素都赋值为3.14。
4. 使用循环结构初始化法:通过循环结构,可以逐个为数组元素赋值。
例如,我们想要创建一个长度为6的整型数组,并将每个元素都初始化为其下标值加1,可以使用以下代码:```javaint[] array = new int[6];for (int i = 0; i < array.length; i++) {array[i] = i + 1;}```这样就创建了一个包含6个元素的整型数组,并将元素依次赋值为1、2、3、4、5和6。
最全面的C C++编码规范总结

最全面的C C++编码规范总结对于不同的编程语言来说,具体的编码规范可以有很大的不同,但是其宗旨都是一致的,就是保证代码在高质量完成需求的同时具备良好的可读性、可维护性。
例如我们可以规定某个项目的C语言程序要遵循这样的规定:变量的命名,头文件的书写和#include 等等。
下面是一些广为采用的编码规范:•GNU Coding Standards•Guidelines for the Use of the C Language in Vehicle Based Software •C++ Coding Guidelines•SUN Code Conventions for Java以下是一些介绍编码、编码规范的书籍:•C++编码规范,陈世忠,人民邮电出版社,2002•高质量程序设计指南:C++/C语言,林锐等,电子工业出版社,2003 注:以下只是根据课题组已有的经验给出的总结,并非对所有场景均适用。
对于高质量的工程,一般会做到:1.代码简洁精炼,美观,可读性好,高效率,高复用,可移植性好,高内聚,低耦合,没有冗余,不符合这些原则,必须特别说明。
2.规范性,代码有规可循。
特殊排版、特殊语法、特殊指令,必须特别说明。
一、文件排版方面1.包含头文件1.1 先系统头文件,后用户头文件。
1.2 系统头文件,稳定的目录结构,应采用包含子路径方式。
1.3 自定义头文件,不稳定目录结构,应在dsp中指定包含路径。
1.4 系统头文件应用:#include <xxx.h>1.5 自定义同文件应用:#include "xxx.h"1.6 只引用需要的头文件。
2.h和cpp文件2.1 头文件命名为*.h,内联文件命名为*.inl;C++文件命名为*.cpp2.2 文件名用大小写混合,或者小写混合。
例如DiyMain vi ew.cpp,infoview.cpp。
不要用无意义的名称:例如XImage.cpp;SView.cpp;xlog.cpp;2.3 头文件除了特殊情况,应使用#ifdef控制块。
java基础知识点整合

面向对象3.1 面向对象介绍1.什么是面向对象对象其实就是现实生活中的各种物体,他们有各种各样的功能,当我们需要借助这些物体去完成我们的需求时,我们就是在面向这些对象,使用它们其中的功能,至于他们其中的功能是如何实现的,我们无需知道,只要能完成需求即可.2.什么是面向对象编程(OOP):Object Oriented Programming 是一种编程思想, 使用对象去进行编程.它的特点有: 封装, 继承, 多态3.对象从哪来:对象是需要先用类来描述, 然后使用类来创建.类是对象的描述, 对象是类的实例.4.面向对象的优点提高代码复用性.使用者无需关心对象其中是如何实现的.让程序员从一个编写者转换成一个使用者.更加符合人的思维能力,使编程更简单.3.2 定义类1.成员变量在类中用变量来描述这一类对象公有的特征.2.成员函数在类中用函数来描述这一类对象公有的行为.3.3 创建和使用对象1.怎么创建使用"new 类名()"形式创建一个对象2.怎么使用通过"."语法来访问类的成员.例如: Person p = new Person(); = "张三";p.eat();3.4对象的初始化过程1.加载类类在第一次使用的时候被加载到内存中2.初始化成员变量当创建对象的时候, 成员变量会初始化为默认值, 基本数据类型都是0, 引用数据类型都是null3.5对象的生命周期1.开始new关键字创建对象的时候, 生命周期开始2.结束没有任何引用指向对象, 该对象成为垃圾, 被虚拟机回收3.6 匿名对象1.什么是匿名对象没有任何引用指向的对象, 就叫匿名对象2.匿名对象有什么特点匿名对象在创建之后立即被回收, 只能使用一次3.7 封装1.什么是封装封装就是将一类事物的特征和行为封装在一个类中,定义成成员变量和成员函数创建对象之后, 这些成员函数可以访问自己的成员变量2.对成员变量的封装使用private关键字将成员变量私有化如果需要对外部提供访问方式, 写公有的get, set方法3.8 构造函数1.什么是构造函数构造函数是一个特殊的函数.函数名必须和类名一致.没有返回值类型.(不等于void,不能写任何返回值).可以写return,但是不能写return+值(尽量不要写).new关键字创建对象时自动调用2.应用场景如果我们希望一段代码在创建对象的时候执行, 就可以写在构造函数中通常我们使用构造函数对成员变量进行赋值3.构造函数和成员变量的执行顺序成员变量优先于构造函数先执行,因为通常使用构造函数都是对成员变量进行初始化,所以如果没有成员变量,构造函数是没有任何意义的.4.构造函数的重载和普通函数一样, 参数列表不同(类型不同,顺序不同,个数不同)即可.重载只与参数列表有关5.构造函数的调用在创建对象时自动调用.在构造函数的第一条语句可以使用"this(被调用的构造函数的实际参数)"的形式调用该类其他构造函数.6.自动生成构造函数在一个类中构造函数是一定存在的.因为在一个类中如果没有写任何的构造函数, 编译时也会自动生成一个无参的构造函数, 里面什么代码都没有.如果写了任何一个构造函数, 那么就不会有自动生成的了注意: 我们在类中只写了一个有参构造函数的时候,这个类就不能使用无参的构造函数创建对象了7.构造函数的访问权限通常构造函数的访问权限都是公有的, 因为构造函数就是为了让别人创建对象时调用的个别情况下在定义类时不希望外部创建对象, 这时可以使用private修饰构造函数, 例如: 单例设计模式(Singleton)3.9 成员代码块(构造代码块)1.什么是成员代码块在类中使用"{}"定义一段代码, 这段代码在创建对象的时候会自动运行2.成员代码块和构造函数的区别构造函数在创建对象的时候是N个选1个调用而代码块是一定执行构造函数可以传入参数代码块不能传入参数3.创建对象时内存中的工作顺序在内存中查找指定的类, 如果没有就加载类, 有则直接引用在内存中开辟一块空间, 将成员变量初始化为默认值, 0和null按照类代码从上到下的顺序, 执行代码块或者成员变量赋值执行构造函数中的代码4.在方法中也可以写代码块(方法代码块),但是不常用3.10成员变量和局部变量1.成员变量在类中定义的变量,(Field),在整个类都可以访问(用于描述着一类事物的共有特征).成员变量随着对象的建立而建立,存在于对象所在的堆内存中.成员变量有默认初始值(0/false/null)2.局部变量在方法/语句中定义的变量(Local Variable),存在于栈内存中.作用范围一结束,变量的空间会自动释放.局部变量是没有初始值的.3.同名问题在同一个作用域中成员变量不能重复, 局部变量也不能重复但是成员变量和局部变量可以同名, 他们互相不冲突4.访问问题在局部变量和成员变量同名的时候, 如果直接用变量名访问一个变量, 那么是先找局部变量, 如果不存在才找成员变量这时如果不想找局部变量, 直接找成员变量, 应该用"this.变量名"3.11 this关键字1.构造函数中"this(参数)"形式可以在构造函数的第一条语句中调用其他的构造函数"this.成员名"形式可以调用当前对象的成员2.普通函数中this用在普通的函数中, 可以代表调用当前函数的对象哪个对象调用this所在的函数,this就代表那个对象.3.内部类中可以使用外部类名.this.成员来访问外部类的成员.3.12静态(static)变量1.什么是静态变量用static修饰的成员变量就是静态变量(随着类的加载而加载)优先于所有非静态成员及成员代码块.2.静态变量和普通变量有什么不同静态变量在类加载后就初始化, 不用创建对象可以直接使用.静态变量被类的所有对象共享(在共享区), 通过一个对象改变, 所有对象都改变.静态变量可以使用"类名.变量名"形式访问, Java推荐使用这种方式, 而不是通过对象访问.3.类在什么时候加载类在第一次使用的时候加载例如: 创建对象, 使用静态变量, 使用静态方法定义变量的时候不加载类.4.静态变量在什么时候使用在定义一个类的时候, 如果希望这个类的所有对象共享一个数据时, 就可以使用静态成员变量.3.13静态(staitc)方法1.什么是静态方法用static修饰的方法就是静态方法静态方法类加载后可以直接运行可以使用"类名.方法名"调用2.什么时候使用静态方法如果一个方法没有访问任何外部的非静态成员, 那么就可以定义为static.这样在调用的时候不用创建对象即可使用, 给人提供方便, 并且效率更高.3. 静态方法使用的注意事项1. 静态方法不能直接访问方法外非静态成员.因为静态方法是随着类的加载而加载的,而非静态成员只有在对象创建才会加载.因此,当静态方法访问方法外非静态成员,对象不一定被创建,所以不能直接访问,除非在静态方法中创建本类对象,才可以访问,方法外静态成员.2. 与静态方法不能直接访问方法外非静态成员相反,非静态方法是可以访问静态成员的,因为,对象被创建了,这个类一定被加载到内存中,所以可以访问.3. 因为静态优先于对象存在,所以在静态方法中是不能出现this,super这两个关键字,道理很简单,静态被加载时还没有对象,而这两个关键字都和对象有关,所以不能使用.4. 静态的利与弊静态好处:1. 如果一个类里的某一个成员变量,他的所有需要共同使用它,没必要每一个对象都存储一份,可以将成员变量设为static,系统将进行单独空间(方法区/静态区) 存储,节省内存空间.2. 静态的成员可以直接被类名调用,使用简单.静态弊端:1. 因为静态是随着类加载而加载的的,所以其生命周期是和类同存亡的.所以生命周期很长,比较浪费内存空间.2. 因为静态只能访问静态,所以访问有一定的局限性.3. 因为主函数是静态的,所以用主函数调用的方法再不创建对象的情况下,只能都是静态的.3.14静态代码块1. 什么是静态代码块用static修饰的代码块类加载后直接运行, 只能执行一次(因为类只会加载一次),如果在一个类中有主函数,他是优先于主函数运行的.不能访问外部非静态成员2. 什么时候用静态代码块在定义一个类的时候, 如果希望某一段代码在别人使用这个类的时候就执行, 那么就可以写在静态代码块中.用于给类初始化.3.15单例设计模式设计模式:解决某一类问题最行之有效的方法.单例设计模式:让一个类只能创建一个对象.懒汉式和饿汉式饿汉式步骤:1.私有化构造函数.2.创建一个对象,并私有(防止类外改变对象内部内容).3.创建一个公有的,静态的方法,返回本类对象,使类外获取本类对象.懒汉式步骤:1.私有化构造函数.2.创建一个对象引用,并私有(防止类外改变对象内部内容).3.创建一个公有的,静态的方法,判断是否创建了一个对象如果创建了,返回本类对象, 如果没有创建,创建一个对象返回,使类外获取本类对象.3.16继承1.什么是继承定义一个类, 使用extends关键字可以继承另一个类, 得到父类的所有非私有属性和方法.2.继承的特点Java只支持单继承, 不支持多继承, 但可以多重继承.一个父类可以有多个子类, 但一个子类只有一个父类.3.java改良多继承的原因?提高代码的安全性,如果一个子类继承多个父类,而这多个父类中有同名的方法,子类要去访问的话,就不知道要访问哪一个方法了.降低了安全性..4.子类对象创建的过程子类对象之所以能调用父类的方法, 是因为在创建子类对象的时候, 其内部创建了一个父类对象.在new一个对象时,会先去子类构造函数,中寻找super()(如果没有显示指定父类构造函数)然后创建父类,然后再回到子类中创建对象.调用子类的方法时, 虚拟机会先在子类中查找是否包含该方法, 如果没有则找父类.在调用子类构造函数的时候, 一定会使用"super(参数)"形式调用父类构造函数创建父类对象.子类中必须要有一个构造函数含有super调用父类构造函数..super和this类似, 都是必须在构造函数的第一条语句使用如果构造函数写了this, 那么则不能写super, 反之亦然如果没写this也没写super, 默认会自动调用父类无参的构造函数5.方法覆盖(重写)覆盖可以让子类将从父类继承来的方法进行扩展,提高代码复用性,减少冗余.覆盖时子父类的方法名子必须相同, 包括返回值,参数列表,并且子类的权限必须大于或等于父类.只能覆盖非私有方法.6.重载(Overload)和重写(Override)的区别:重载:名字相同,参数列表不同只与参数列表相同.重写:子父类的方法名子必须相同, 包括返回值,参数列表,子类的权限必须大于或等于父类.(如果父类返回值是一个类,子类返回值可以是和父类相同的类或其子类).7.向上转型子类可以当作父类使用, 因为父类的功能子类都有Fu f = new Zi();如果一个方法要求传入一个父类类型对象, 我们也可以传入一个子类对象8.强制类型转换在子类当作父类来用时, 不能调用子类特有的成员.如果一定要调用, 需要把父类类型强转回子类类型.这种转换叫强制类型转换, 在编译时不论类型是否匹配都不会报错, 为了程序安全, 通常在转换之前使用instanceof进行判断.3.17Object类及其中常用方法1.什么是Object类Object类是Java中所有类的父类, 如果定义一个类不继承任何类, 默认继承ObjectObject类中的方法会被所有的类继承2.finalize任何对象在成为垃圾被销毁之前, 都会调用finalize 方法Object类中的finalize方法是空的, 什么都没有当我们希望在对象被销毁之前执行一段代码, 就可以在类中重写finalize方法, 把要执行的代码写在方法中.3.toStringtoString方法可以将一个对象转为字符串表示形式Object类中的toString方法返回的是"类名@内存地址"当我们希望调用toString时返回成员变量的值, 就可以重写该方法调用System.out.println()方法时会自动打印对象toString的返回值4.equalsequals方法是用来比较两个对象的Object类中equals方法默认比较的是对象的地址如果我们希望比较两个对象的属性, 那么可以重写equals方法, 在方法内比较所有的属性在比较字符串时如果希望比较两个字符串的内容, 就需要使用equals, String类是重写了equals的3.18 组合设计模式1.什么是组合设计模式在我们定义一个类的时, 如果需要使用另外一个类的方法, 就可以用组合设计模式.2.组合设计模式的写法在类中定义一个被组合类型的成员变量通过构造函数组合一个对象, 用成员变量引用在方法中使用成员变量调用被组合对象的方法3.组合设计模式和继承的区别不占用继承的位置, 当前类组合一个类之后还能继承其他类组合设计模式组合的类不能当作被组合的类使用3.19 多态1.多态的体现父类引用指向子类对象.(父类的引用可以接受自己的子类).2.多态的前提类与类之间必须有关系,要么继承,要么实现.子类与父类存在覆盖,因为在不强转的情况下,父类,不能访问子类特有的方法.3.多态的好处提高代码扩展性.4多态的弊端虽然提高了扩展性,但是只能使用父类父类引用访问父类成员(共有成员),为了能访问子类特有方法,父类的引用必须转成子类类型(向下转型).3.20 抽象1.什么是抽象类用abstract修饰的类就是抽象类, 抽象类中可以定义抽象方法2.什么是抽象方法用abstract修饰的方法就是抽象方法, 抽象方法在子类中必须全部重写3.什么时候用抽象类和抽象方法在我们定义类的时候, 如果多个类有相同的方法, 那么就应该把这些方法抽取到父类中定义完全相同的方法直接在父类中定义并实现, 如果只有方法签名(无方法体)一样而实现不同, 那么就可以在父类中定义抽象方法这样别人看到父类的时候就知道子类都有什么功能了, 方便他人阅读我们的代码, 也更好的支持了多态.4.抽象类细节有抽象方法的类必须声明为抽象类, 抽象类可以没有抽象方法抽象类不能创建对象子类继承抽象类时必须重写所有的抽象方法3.21 final修饰符1. final代表最终的, 可以用来修饰类, 方法, 变量.2. 被final修饰后的特点final的类不能被继承final的方法不能被重写final的变量只能赋值一次,在程序运行结束前,会一直存在与内存中.如果内部类在局部位置上,只能访问该局部中被final 修饰的变量.被final修饰的形参,第一次赋值是在调用它所在的函数时,不能再次赋值了.被final修饰的引用类型变量,不能在指向其他对象,但是他第一次指向的对象中的内容是可以改变的.final 只是修饰了引用.public static final 修饰的变量时全局变量,可以使用类名调用,名字全部大写3.22模板设计模式1.什么是模板设计模式在编程的过程当中, 如果经常要做一些类似的事, 其中某些步骤相同, 有些步骤不同, 这是就可以使用模板设计模式2.怎么使用模板设计模式定义一个抽象类定义一个final的方法在方法中写出每次相同的步骤, 不同的步骤写成抽象方法, 调用抽象方法每次实现不同的步骤时, 定义子类继承抽象类, 重写抽象方法即可, 相同的步骤无需重写直接调用final方法3.23接口1.什么是接口接口是一种特殊的抽象类2.接口和抽象类的区别抽象类用abstract class定义, 接口用interface定义抽象类中可以有不抽象的方法, 接口中所有方法都是抽象的抽象类用extends继承, 接口用implements实现抽象类可以继承抽象类, 接口可以继承接口抽象可以继承接口,接口不能继承抽象因为抽象类里面有可能会有非抽象方法..抽象类中的方法没有默认修饰符, 接口中的方法默认是public abstract修饰的抽象类中的成员变量没有默认修饰符, 接口中的成员变量默认是public static final 修饰的一个类只能继承一个抽象类, 一个类可以实现多个接口3.什么时候用抽象类, 什么时候用接口能用接口的时候就不用抽象类(没有任何不抽象的方法), 因为接口不占用继承位置如果需要定义不抽象的方法, 那么就必须使用抽象类.3.24 策略设计模式定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。
Java基础知识总结(超详细整理)

Java基础知识总结(超详细整理)Java语⾔的特点1.⾯向对象⾯向对象(OOP)就是Java语⾔的基础,也是Java语⾔的重要特性。
⾯向对象的概念:⽣活中的⼀切事物都可以被称之为对象,⽣活中随处可见的事物就是⼀个对象,我们可以将这些事物的状态特征(属性)以及⾏为特征(⽅法)提取并出来,并以固定的形式表⽰。
2.简单好⽤Java语⾔是由C和C++演变⽽来的,它省略了C语⾔中所有的难以理解、容易混淆的特性(⽐如指针),变得更加严谨、简洁、易使⽤。
3.健壮性Java的安全检查机制,将许多程序中的错误扼杀在摇蓝之中。
另外,在Java语⾔中还具备了许多保证程序稳定、健壮的特性(强类型机制、异常处理、垃圾的⾃动收集等),有效地减少了错误,使得Java应⽤程序更加健壮。
4.安全性Java通常被⽤在⽹络环境中,为此,Java提供了⼀个安全机制以防恶意代码的攻击,从⽽可以提⾼系统的安全性。
5.平台⽆关性Java平台⽆关性由Java 虚拟机实现,Java软件可以不受计算机硬件和操作系统的约束⽽在任意计算机环境下正常运⾏。
6.⽀持多线程在C++ 语⾔没有内置的多线程机制,因此必须调⽤操作系统的多线程功能来进⾏多线程程序设计,⽽ Java 语⾔却提供了多线程⽀持。
多线程机制使应⽤程序在同⼀时间并⾏执⾏多项任务,该机制使得程序能够具有更好的交互性、实时性。
7.分布式(⽀持⽹络编程)Java语⾔具有强⼤的、易于使⽤的⽹络能⼒,⾮常适合开发分布式计算的程序。
java中提供了⽹络应⽤编程接⼝(),使得我们可以通过URL、Socket等远程访问对象。
8.编译与解释共存Java语法基础标识符: ⽤来标识类名、对象名、变量名、⽅法名、类型名、数组名、⽂件名的有效字符序列。
合法的标识符:由字母、数字、下划线“_”、美元符号“$”或者“¥”组成,并且⾸字符不能是数字。
不能把java关键字和保留字作为标识符。
标识符对⼤⼩写敏感。
关键字:Java语⾔中已经赋予了特定含义的保留字: const、goto,Java版本中尚未使⽤,但以后版本可能会作为关键字使⽤变量:程序运⾏期间可以被改变的量。
java类代码执行顺序

java类代码执行顺序
在 Java 类中,代码的执行顺序如下:
1. 父类静态初始化块:首先执行父类的静态初始化块。
静态初始化块位于类的第一次初始化最前端执行,先父类后子类。
2. 子类静态初始化块:接着执行子类的静态初始化块。
3. 子类`main`方法:然后执行子类的`main`方法。
4. 父类初始化块:在每次对象被构造器初始化前执行父类的初始化块。
5. 父类构造器:执行父类的构造器。
6. 子类初始化块:执行子类的初始化块。
7. 子类构造器:最后执行子类的构造器。
上述执行顺序仅针对普通的 Java 类,不包括特殊情况或高级特性。
jav构造函数及相关知识

java 构造函数一般我们讲的“函数”就是“方法”;构造函数=构造方法;构造方法是一种特殊的方法,具有以下特点。
(1)构造方法的方法名必须与类名相同。
(2)构造方法没有返回类型,也不能定义为void,在方法名前面不声明方法类型。
(3)构造方法的主要作用是完成对象的初始化工作,它能够把定义对象时的参数传给对象的域。
(4)一个类可以定义多个构造方法,如果在定义类时没有定义构造方法,则编译系统会自动插入一个无参数的默认构造器,这个构造器不执行任何代码。
(5)构造方法可以重载,以参数的个数,类型,或排列顺序区分。
java 构造函数的执行过程类初始化时构造函数调用顺序:(1)初始化对象的存储空间为零或null值;(2)调用父类构造函数;(3)按顺序分别调用类成员变量和实例成员变量的初始化表达式;class Dollar {Money m = new Money();Rmb r = new Rmb();public Dollar() {System.out.println("Dollar is construct!");}public static void main(String[] args) {new Dollar();}}class Money {public Money() {System.out.println("Money is construct!");}}class Rmb {public Rmb() {System.out.println("RMB is construct!");}}构造方法在Java中,任何变量在被使用前都必须先设置初值.Java提供了为类的成员变量赋初值的专门方法:构造方法(constructor)构造方法是一种特殊的成员方法,它的特殊性反映在如下几个方面:1.构造方法的名字必须与定义他的类名完全相同,没有返回类型,甚至连void 也没有。
JAVA面向对象程序设计教学大纲.doc

《JAVA面向对象程序设计》课程教学大纲Oriented object Programming in JAVA编号:08065121适用专业:计算机科学与技术、网络工程学时数:32 学分数:2执笔者:田小玲编写日期:2009年11月一、课程的性质和目的本课程是为计算机科学与技术以及网络工程专业本科生开设的专业选修课,是一门面向对象的编程语言,通过本课程的学习,培养和提高学生面向对象程序设计的能力和Java语言在web开发中的应用能力。
二、课程教学内容第一章面向对象软件开发概述(2学时)1.内容面向对象问题求解的提出、面向对象问题求解的概述、对象、类与实体、对象的属性与相互关系、面向对象的软件开发过程、面向对象程序设计方法的优点、开发环境设置及开发工具简介。
2.要求(1)了解:面向对象软件开发概述,面向对象的软件开发过程及面向对象程序设计方法的优点。
(2)掌握:对象的属性与相互关系,对象、类与实体的基本概念。
(3)熟练掌握:开发环境设置及开发工具简介(补充)。
3.重点对象、类与实体的基本概念。
4滩点面向对象程序设计方法的理解。
第二章Java概述(2学时)1.内容Java语言的特点、Java虚拟机及垃圾回收机制、JDK目录结构、Java的API结构及Java 程序结构、第一个Java Application程序、第一个Java Applet程序、图形界面的输入输出、字符界面的输入输出。
2.要求(1)了解:Java语言的发展历史及特点,Java Application程序及Java Applet程序,图形界面的输入输出,字符界面的输入输出。
(2)掌握:Java语言实现机制(补充),Java体系结构(补充)。
(3)熟练掌握:Java Application程序的结构。
3.重点Java Application 程序的结构。
4滩点Java语言实现机制。
第三章Java语言基础(2学时)1.内容数据类型、变量与常量、表达式、流程控制语句。
答案JAVA程序设计基础(复习提纲及练习题

复习....参考考试题型:1.单项选择题(本大题共15小题,每小题1分,共15分)2. 判断题(10小题,每小题1分,共10分)3.填空题(本大题共10空,每个空2分,共20分)4.阅读程序,写出程序运行后的输出结果(本大题共3小题,每小题6分,共18分)5. 编程题(本大题共3小题,共37分),其中第1题:9分(位操作),第2题14(分排序或字符串处理),第3题14分(类与对象)。
涉及数组、排序、字符串处理、类和对象(实例)、位操作(手写推算步骤及最终结果,要求看样题)等。
考试涉及的相关知识点:1.java程序类型:(1)java application(需主类)、java程序、源程序、类、接口、字节码文件、包、JDK JVM javac.exe java.exe跨平台java开发步骤一二维数组等(2)java applet:java小程序(可以没有主类,是图形界面),主要用于网页(3)java script:网页或网站的“脚本”程序2.标识符和关键字:class、interface final abstract static void byte short int long float double boolean String return 异常常用的关键字(try catch finally throw throws)3.表达式:=比较运算符:> >= < <= != ==逻辑运算符:&& || !位运算符:& |~ ^ >> >>> <<instanceof ++ -- 前后关系?:算合语句s+=5 s-=5 s*=5 s/=5 int a=b=10;4.程序控制结构:顺序、选择、循环(1)单路选择结构if(){ }(2)多路选择结构if( ) {.. else ..}(3)else if 结构(4)switch (break);while(){ … }do{ …. } while( ); break continuefor( ; ; ){ … }5.面向对象的程序设计:类:class 成员变量方法成员修饰符(访问、特征)static变量成员或方法实例变量成员或方法UML图对象:Object 创造对象new方法:void 方法、非void 方法、static 方法(类方法)、非static 方法(实例方法)方法参数传递:实参形参传值传引用(数组对象接口)多态:重载重写this 、super构造方法(在类的继承中可能用到的关键字super)包:关键字import 、package继承(组合:主类main() 与继承):继承创新改造子类不能降低父类的访问级别Super、this 、上转型对象Abstract、final接口:interface(1)实现:implements 也是一种继承(包括一般类与抽象类,多实现)(2)继承:extends (与类相比的“多继承”)(3)静态块(静态初始化器) static { …}、构造块{…}、构造方法以及在类的继承和实例生成中的相互关系和执行顺序。
Java中的static修饰int值做全局变量与static修饰词初始化顺序

Java中的static修饰int值做全局变量与static修饰词初始化顺序先看⼀道题1public class HasStatic{2private static int x=100;3public static void main(String args[]){4 HasStatic hs1=new HasStatic();5 hs1.x++;6 HasStatic hs2=new HasStatic();7 hs2.x++;8 hs1=new HasStatic();9 hs1.x++;10 HasStatic.x--;11 System.out.println("x="+x);12 }13 }这个题的考察点主要是在static关键字上⾯static修饰的全局变量到底是在什么时候创建的?这个题⾥⾯⼀共是有⼏个不同对象的x属性还是其他的什么呢?下⾯附上⼀张我学JavaSE时候关于static关键字的PPT截图通过这个图上⾯的知识点就很容易计算上⾯的题⽆论哪个对象操作了x这个全局变量,x的值都是在改变的 x最后的取值应该为102那么扩展起来这个知识点联想⼀下 static修饰的⽅法属性代码块都是什么时候创建的呢?⾸先我们看java中类的⽣命周期java中类的⽣命周期为装载、连接、初始化、使⽤和卸载五个过程,如下图所⽰:1.加载我们编写⼀个java的源⽂件,经过编译后⽣成⼀个后缀名为.class的⽂件,这结合四字节码⽂件,java虚拟机就识别这种⽂件,java的⽣命周期就是class⽂件从加载到消亡的过程。
关于加载,其实,就是将源⽂件的class⽂件找到类的信息将其加载到⽅法区中,然后在堆区中实例化⼀个ng.Class对象,作为⽅法区中这个类的信息的⼊⼝。
但是这⼀功能是在JVM之外实现的,主要的原因是⽅便让应⽤程序⾃⼰决定如何获取这个类,在不同的虚拟机实现的⽅式不⼀定相同,hotspot虚拟机是采⽤需要时在加载的⽅式,也有其他是先预先加载的。
构造块 静态块 构造块 构造块

静态块、构造块、构造方法是Java中常见的三种代码块。
它们都有自己的特点和作用,本文将分别介绍它们的概念、用法及实例。
一、静态块静态块是在类加载时自动执行的代码块,用于初始化静态变量。
静态块的语法格式为:```javastatic {// 静态块中的代码}```静态块可以有多个,按照出现顺序依次执行。
它们在程序启动时执行一次,且只执行一次。
以下是一个静态块的例子:```javapublic class StaticBlockExample {static {System.out.println("静态块1执行");}static {System.out.println("静态块2执行");}public static void main(String[] args) {System.out.println("main方法执行");}}```输出结果为:```静态块1执行静态块2执行main方法执行```从输出结果可以看出,静态块在main方法执行之前执行,且按照出现顺序依次执行。
二、构造块构造块是在创建对象时自动执行的代码块,用于初始化实例变量。
构造块的语法格式为:```java{// 构造块中的代码}```构造块可以有多个,按照出现顺序依次执行。
它们在每次创建对象时执行一次。
以下是一个构造块的例子:```javapublic class ConstructorBlockExample {{System.out.println("构造块1执行");}{System.out.println("构造块2执行");}public ConstructorBlockExample() {System.out.println("构造方法执行");}public static void main(String[] args) {new ConstructorBlockExample();}}```输出结果为:```构造块1执行构造块2执行构造方法执行```从输出结果可以看出,构造块在构造方法执行之前执行,且按照出现顺序依次执行。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
同样,我们还是写一个类来进行测试:
Java代码
public class TestOrder { // 静态变量 public static TestA a = new TestA();
public class TestStaticCon { public static int a = 0;
static { a = 10; System.out.println("父类的非静态代码块在执行a=" + a);
}
{ a = 8; System.out.println("父类的非静态代码块在执行a=" + a);
我们大家都知道,对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化 顺序以此是(静态变量、静态初始化块)>(变量、初始化块)>构造器。我们也可以通过下 面的测试代码来验证这一点:
Java代码 public class InitialOrderTest {
// 静态变量 public static String staticField = "静态变量"; // 变量 public String field = "变量";
java 类静态域、块,非静态域、块,构造函数的初始化顺序
面试的时候,经常会遇到这样的考题:给你两个类的代码,它们之间是继承的关系,每个类 里只有构造器方法和一些变量,构造器里可能还有一段代码对变量值进行了某种运算,另外 还有一些将变量值输出到控制台的代码,然后让我们判断输出的结果。这实际上是在考查我 们对于继承情况下类的初始化顺序的了解。
}
public static void main(String[] args) { TestStaticCon tsc = null; System.out.println("!!!!!!!!!!!!!!!!!!!!!"); tsc = new TestStaticCon();
} }
运行结果: 父类的非静态代码块在执行a=10 !!!!!!!!!!!!!!!!!!!!! 父类的非静态代码块在执行a=8 a在父类带参构造方法中的值:10 8 8 父类无参构造方法在执行 a=8
new SubClass(); } }
运行一下上面的代码,结果马上呈现在我们的眼前: 父类--静态变量 父类--静态初始化块 子类--静态变量 子类--静态初始化块 父类--变量 父类--初始化块 父类--构造器 子类--变量 子类--初始化块 子类--构造器
现在,结果已经不言自明了。大家可能会注意到一点,那就是,并不是父类完全初始化完毕 后才进行子类的初始化,实际上子类的静态变量和静态初始化块的初始化是在父类的变量、 初始化块和构造器初始化之前就完成了。
} // 初始化块 {
System.out.println(s_Field); System.out.println("子类--初始化块"); }
// 构造器 public SubClass() {
System.out.println("子类--构造器"); }
// 程序入口 public static void main(String[] args) {
// 初始化块 {
System.out.println(p_Field); System.out.println("父类--初始化块"); }
// 构造器 public Parent() {
System.out.println("父类--构造器"); } }
public class SubClass extends Parent { // 静态变量 public static String s_StaticField = "子类--静态变量"; // 变量 public String s_Field = "子类--变量"; // 静态初始化块 static { System.out.println(s_StaticField); System.out.println("子类--静态初始化块");
System.out.println("构造器"); }
public static void main(String[] args) { new InitialOrderTest();
}
}
运行以上代码,我们会得到如下的输出结果: 静态变量 静态初始化块 变量 初始化块 构造器
这与上文中说的完全符合。那么对于继承情况下又会怎样呢?我们仍然以一段测试代码来获 取最终结果:
大家可以随意改变变量 a、变量 b 以及静态初始化块的前后位置,就会发现输出结果随着它 们在类中出现的前后顺序而改变,这就说明静态变量和静态初始化块是依照他们在类中的定 义顺序进行初始化的。同样,变量和初始化块也遵循这个规律。
了解了继承情况下类的初始化顺序之后,如何判断最终输出结果就迎刃而解了。
测试函数:
两者的区别就是:静态代码块是自动执行的;
静态方法是被调用的时候才执行的.
作用:静态代码块可用来初始化一些项目最常用的变量或对象;静态 方法可用作不创建对象也可能需要执行的代码.
} }
class TestA { public TestA() { System.out.println("Test--A"); }
}
class TestB { public TestB() { System.out.println("Test--B"); }
}
运行上面的代码,会得到如下的结果:
Test--A 静态初始化块 Test--B
// 静态初始化块 static {
System.out.println(staticField); System.out.println("静态初始化块"); }
// 初始化块 {
System.out.println(field); System.out.println("初始化块"); }
// 构造器 public InitialOrderTest() {
结论:静态代码块是在类加载时自动执行的,非静态代码块是在创建对 象时自动执行的代码,不创建对象不执行该类的非静态代码块。且执行 顺序为静态代码块------非静态代码块----构造函数。
扩展:静态代码块 与 静态方法:
一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需 要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初 始化,在不创建对象的情况下,其他程序来调用的时候,需要使用静态方 法,这种代码是被动执行的.
}
public TestStaticCon() { this("a在父类带参构造方法中的值:" + TestStaticCon.a); // 调用另外一
个构造方法 System.out.println(a); System.out.println("父类无参构造方法在执行a=" + a);
}
public TestStaticCon(String n) { System.out.println(n); System.out.println(a);
// 静态初始化块 static {
System.out.println("静态初始化块"); }
// 静态变量 public static TestB b = new TestB();
public static void main(String[] args) { new TestOrder();
Java代码 class Parent {
// 静态变量 public static String p_StaticField = "父类--静态变量"; // 变量 public String p_Field = "父类--变量";
// 静态初始化块 static {
System.out.println(p_StaticField); System.out.println("父类--静态初始化块"); }