Java笔记(一)

1. 构造代码块:

 1 class Person{
 2     private String name;
 3     private int age;
 4     
 5     /*
 6     构造代码块
 7     作用:给对象进行初始化。
 8     对象一建立就运行,而且优先于构造函数执行。
 9     和构造函数的区别:构造代码块是给所有对象进行统一初始化,
10     而构造函数是给对应的对象进行初始化。
11     
12     构造代码块中的定义的是不同对象共性的初始化内容。
13     */
14     {
15         System.out.println("Hello!");
16     }
17 }

2.this关键字用于构造函数间互相调用:

 1 //this语句只能定义在构造函数的第一行,因为初始化要先执行
 2 class Person{
 3     private String name;
 4     private int age;
 5     Person(){}
 6     Person(String name){
 7         this();
 8         this.name = name;
 9     }
10     Person(String name, int age){
11         this(name); //p(name);
12         this.age = age;
13     }
14 }

3. 静态:static

  (1)用法:是一个修饰符,用于修饰成员(成员变量,成员函数)。

    当成员被静态修饰后,就多了一个调用方式,除了可以被对象调用外还可以直接被类名调用。类名.静态成员。

    (2)特点:随着类的加载而加载(即静态会随着类的消失而消失,说明它的生命周期最长);优先于对象存在;被所有对象所共享;可以直接被类名所调用。

    成员变量=实例变量

  静态成员变量=类变量

    (3)实例变量和类变量的区别:

  存放位置:类变量随着类的加载而存在于方法区(共享区)中,实例变量随着对象的建立而                      存在于堆内存中;

  生命周期:类变量生命周期最长,随着类的消失而消失,实例变量生命周期随着对象的消失而消失。

  (4)静态的使用注意事项:

    静态方法只能访问静态成员;非静态方法既可以访问静态也可以访问非静态。

    静态方法中不可以定义this,super关键字,因为静态优先于对象存在。

    主函数是静态的。

  (5)静态有利有弊:

    利:对对象的共享数据进行单独空间的存储,节省空间。没有必要对每一个对象都存储一份。可以直接被类名调用。

    弊:生命周期过长。访问出现局限性(只能访问静态)。

3. 主函数:是一个特殊的函数。作为程序的入口,可以被JVM调用。

 main不是关键字,是一个特殊的单词,可以被JVM识别,固定格式。

 JVM在调用主函数时,传入的是new String[0]

4. 静态代码块:随着类的加载而执行,只执行一次,并优先于主函数,用于给类进行初始化。

 1 class text1{
 2     static{
 3         System.out.println("b");
 4     }
 5     public static void main(String[] args) {
 6         new text2();
 7         new text2();
 8         System.out.println("over");
 9     }
10     static{
11         System.out.println("c");
12     }
13 }
14 
15 class text2{
16     static{
17         System.out.println("a");
18     }
19 }

执行java text1

输出

b

c

a

over

5. 对象的初始化过程:

  Person p = new Person("ztq", 22);

  (1)因为new用到了Person.class,所以会先找到Person.class文件并加载到内存中。

  (2)执行该类中的static代码块,如果有的话,给Person.class类进行初始化。

  (3)在堆内存中开辟空间,分配内存地址。

  (4)在堆内存中建立对象的特有属性,并进行默认初始化。

  (5)对属性进行显示初始化。

  (6)对对象进行构造代码块初始化。

  (7)对对象进行与之对应的构造函数初始化。

  (8)将内存地址赋给栈内存中的p变量。

6. 接口:可以认为是一个特殊的抽象类,当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示。用interface定义。接口是对外暴露的规则,是程序的功能扩展。

 接口定义时,格式特点:

  (1)接口中常见定义:常量,抽象方法。

  (2)接口中的成员都有固定修饰符。常量:public static final 方法:public abstract

 接口中的成员都是public

 接口不可以创建对象,因为有抽象方法,需要被子类实现,子类对接口中的抽象方法全部覆盖后,子类才可以实例化,否则子类是一个抽象类。

 接口可以被类多实现。这也是对多继承不支持的转换形式。

 接口之间可以多继承。

7. 多态:可以理解为事物存在的多种体现形态。

 多态的体现:父类的引用指向了自己的子类对象,也可以接收自己的子类对象。

 多态的前提:必须是类与类之间有关系,要么继承,要么实现。存在覆盖。

 多态的好处:提高程序的扩展性。

 多态的弊端:提高了扩展性,但是只能使用父类的引用访问父类中的成员。

 

 在多态(父类引用指向子类对象)中成员函数(非静态)的特点:

  在编译时期:参阅引用性变量所属的类中是否有调用的方法,如果有,编译通过,没有则失败。

  在运行时期:参阅对象所属的类中是否有调用的方法。

  总结:成员函数在多态调用时,编译看左边,运行看右边。

 在多态中成员变量的特点:

  无论编译和运行,都参考左边(引用型变量所属的类)。

 在多态中静态成员函数的特点:

  无论编译和运行,都参考左边。

8.  内部类:将一个类定义在另一个类的里面,对里面那个类就成为内部类(内置类,嵌套类),可以被私有化。

  访问特点:内部类可以直接访问外部类中的成员,包括私有成员。

       而外部类要访问内部类中的成员必须要建立内部类的对象。

  访问格式

  (1)当内部类定义在外部类的成员位置上,而且非私有。可以在外部其他类中,直接建立内部类对象。

  外部类名.内部类名 变量名 = 外部类对象.内部类对象

   Outer.Inner in = new Outer().new Inner();

  (2)当内部类在成员位置上,就可以被成员修饰符所修饰。比如:private:将内部类在外部类中进行封装。static:内部类就具备了static的特性(静态内部类),只能访问外部类中的的static成员,出现了访问局限。在外部类中直接访问静态内部类的非静态成员 new Outer.Inner().function();

  注意:当内部类中定义了静态成员,该内部类必须是static的。

     当外部类中的静态方法访问内部类时,内部类也必须是static的。

      内部类定义在局部时,不可以被成员修饰符修饰,可以直接访问外部类中的成员,                   因为还持有外部类中的引用,但是不可以访问它所在的局部中的变量,只能访问被                   final修饰的局部变量。 如下边代码:

 1 class Outer{
 2     int x = 3;
 3     void method(){
 4         final int y = 4; 
 5         class Inner{
 6             void function(){
 7                 System.out.println(y);
 8             }
 9         }
10         new Inner().function();
11     }
12 }

 当描述事物时,事物的内部还有事物,该事物用内部类来描述。 

 匿名内部类就是内部类的简写格式。

 定义匿名内部类的前提:内部类必须是继承一个类或者实现接口。

 匿名内部类的格式:new 父类或者接口(){定义子类的内容}

 其实匿名内部类就是一个匿名子类对象。 

 1 abstract class AbsDemo{
 2     abstract void show();
 3 }
 4 
 5 class Outer{
 6     int x = 3;
 7     /*
 8     class Inner extends AbsDemo{
 9         void show(){
10             System.out.println("show: " + x);
11         }
12     }
13     */
14     public void function(){
15         //new Inner().show();
16         new AbsDemo(){
17             void show(){
18                 System.out.println("show: " + x);
19             }
20         }.show();
21     }
22 }

 例:补全代码,通过匿名内部类

 1 interface Inter{
 2     void method();
 3 }
 4 
 5 class Test{
 6     //补足代码,通过匿名内部类
 7 }
 8 
 9 public class InnerClassTest{
10     public static void main(String[] args) {
11         Test.function().method();
12     }
13 }

 由Test.function()可知Test类中有静态方法function(),但不知道返回类型。后面跟着.method(),又因为method()方法必然是非静态的,所以function()返回的是一个对象,因为只有对象才能调用method()方法。又知道只有Inter的对象才能调用method()方法,但Inter不能new对象,只有它的子类可以。因为function()方法时静态的,所以需要定义一个静态的内部类。

 1 interface Inter{
 2     void method();
 3 }
 4 
 5 class Text{
 6     
 7     static Inter function(){
 8         return new Inter(){
 9             public void method(){
10                 System.out.println("method run");
11             }
12         };
13     }
14 }
15 
16 public class InnerClassTest{
17     public static void main(String[] args) {
18         Text.function().method();
19     }
20 }

 注:当使用的方法的参数类型是接口类型时,且该接口中的方法不超过3个,这时可以定义一个匿名内部类作为参数。如:

 1 public class InnerClassTest{
 2     public static void main(String[] args) {
 3         
 4         show(new Inter(){
 5             public void method(){
 6                 System.out.println("method show run");
 7             }
 8         });
 9     }
10     
11     public static void show(Inter in){
12         in.method();
13     }
14 }

9.  对捕获到的异常对象进行常见方法操作:

  String getMessage():获取异常信息

  String toString():异常名称,异常信息

  void  printStackTrace():异常名称,异常信息,异常出现的位置,其实JVM默认的异常处理机制就是在调用printStackTrace()方法,打印异常的堆栈跟踪信息

  对多异常的处理:

  (1)声明异常时,建议声明更为具体的异常。这样处理得可以更具体;

  (2)对方声明几个异常,就对应有几个catch块,不要定义多余的,如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面;

  (3)自定义异常: 自定义类必须继承Exception

    原因:异常体系有一个特点,因为异常类和异常对象都被抛出。它们都具备可抛性,这                      个可抛性是Throwable这个体系中独有特点,这有这个体系中的类和对象才可                        以被throws和throw操作。

  注:自定义异常时,如果该异常的发生,无法再继续进行运算,就让自定义异常继承RuntimeException

 1 class minusException extends Exception{
 2     private int value;
 3     minusException(){}
 4     minusException(String msg){
 5         super(msg);
 6     }
 7     minusException(String msg, int value){
 8         super(msg);
 9         this.value = value;
10     }
11     public int getValue(){
12         return value;
13     }
14 }
15 
16 class Demo{
17     public int div(int a, int b) throws minusException, ArithmeticException{
18         if(b < 0){
19             throw new minusException("除数出现了负数", b);
20         }
21         else if(b == 0){
22             throw new ArithmeticException("除数出现了0");
23         }
24         return a / b;
25     }
26 }
27 
28 public class text{
29     public static void main(String[] args) {
30         Demo d = new Demo();
31         try{
32             int x = d.div(4, 0);
33             System.out.println("x = " + x);
34         }catch(minusException e){
35             System.out.println(e.toString());
36             System.out.println("除数是:" + e.getValue());
37         }catch(ArithmeticException e){
38             System.out.println(e.toString());
39         }finally{
40             System.out.println("over");
41         }
42     }
43 }

 throws和throw的区别:

  (1)throws使用在函数上,throw使用在函数内

  (2)throws后面跟的是异常类,可以跟多个,用逗号隔开。throw后面跟异常对象。

 注:Exception中有一个特殊的子类异常RuntimeException(运行时异常)。如果在函数内容抛出该异常,函数上可以不用声明,编译也可以通过。如果在函数上声明了该异常,调用者可以不用进行处理(即不用try或者抛)。之所以不用在函数上声明,是因为不需要让调用者处理。当该异常发生,希望程序停止。因为在运行时,出现了无法继续运算的情况,希望停止程序后,对代码进行修正。

 格式:try-catch,try-catch-finally,try-finally

 异常在子父类覆盖中的体现:

  (1)子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法只能抛出父类的异常或者该异常的子类。

  (2)如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。

  (3)如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。如果子类方法抛出了异常,就必须要进行try处理。绝对不能抛出。

 注:finally只有一种情况不会被执行。当执行到System.exit(0); finally不会执行。

 例:

  (1)

 1 //写出程序结果
 2 class Demo{
 3     public static void func(){
 4         try{
 5             throw new Exception();
 6         }finally{
 7             System.out.println("B");
 8         }
 9     }
10     public static void main(String[] args) {
11         try{
12             func();
13             System.out.println("A");
14         }catch(Exception e){
15             System.out.println("C");
16         }
17         System.out.println("D");
18     }
19 }

编译失败。func()中抛出了一个编译时异常,并没有进行处理(没有catch,也没有在方法上声明抛出),如果方法上声明了该异常,则结果是:B C D。首先,func()方法try中抛出异常,后面的finally执行输出B,A不输出,直接跳到catch中,输出C,最后输出D。

(2)

 1 //写出程序结果
 2 class Test{
 3     Test(){
 4         System.out.println("Test");
 5     }
 6 }
 7 
 8 public class Demo extends Test{
 9     Demo(){
10         super();
11         System.out.println("Demo");
12     }
13     public static void main(String[] args) {
14         new Demo();
15         new Test();
16     }
17 }

输出结果:Test Demo Test

(3)

 1 //写出程序结果
 2 interface A{}
 3 
 4 class B implements A{
 5     public String func(){
 6         return "func";
 7     }
 8 }
 9 
10 public class Demo{
11     public static void main(String[] args) {
12         A a = new B();
13         System.out.println(a.func());
14     }
15 }

编译失败。接口A中并没有func()方法。

(4)

 1 //写出程序结果
 2 class Fu{
 3     boolean show(char a){
 4         System.out.println(a);
 5         return true;
 6     }
 7 }
 8 
 9 class Demo extends Fu{
10     public static void main(String[] args) {
11         int i = 0;
12         Fu f = new Demo();
13         Demo d = new Demo();
14         for(f.show('A'); f.show('B') && (i < 2); f.show('C')){
15             i++;
16             d.show('D');
17         }
18     }
19     boolean show(char a){
20         System.out.println(a);
21         return false;
22     }
23 }

输出结果:A B

(5)

 1 //写出程序结果
 2 interface A{}
 3 
 4 class B implements A{
 5     public String test(){
 6         return "yes";
 7     }
 8 }
 9 
10 public class Demo{
11     static A get(){
12         return new B();
13     }
14     public static void main(String[] args) {
15         A a = get();
16         System.out.println(a.test());
17     }
18 }

编译失败。接口A中没有test()方法。

(6) 

 1 //写出程序结果
 2 class Super{
 3     int i = 0;
 4     public Super(String a){
 5         System.out.println("A");
 6     }
 7     public Super(){
 8         System.out.println("B");
 9         i += 2;
10     }
11 }
12 
13 public class Demo extends Super{
14     public Demo(String a){
15         System.out.println("C");
16         i = 5;
17     }
18     public static void main(String[] args) {
19         int i = 4;
20         Super d = new Demo("A");
21         System.out.println(d.i);
22     }
23 }

输出结果:B C 5。先执行super(),即Super(),输出B,i变为2。接着执行Demo的构造方法,输出C,i变为5。

(7)

 1 interface Inter{
 2     void show(int a, int b);
 3     void func();
 4 }
 5 
 6 public class Demo{
 7     public static void main(String[] args) {
 8         //补足代码:调用两个函数,要求用匿名内部类
 9         Inter in = new Inter(){
10             public void show(int a, int b){
11                 
12             }
13             
14             public void func(){
15                 
16             }
17         };
18         in.show(1, 2);
19         in.func();
20     }
21 }

(8)

 1 //写出程序结果
 2 class TD{
 3     int y = 6;
 4     class Inner{
 5         static int y = 3;
 6         void show(){
 7             System.out.println(y);
 8         }
 9     }
10 }
11 
12 class TC{
13     public static void main(String[] args) {
14         TD.Inner ti = new TD().new Inner();
15         ti.show();
16     }
17 }

编译失败:TD类中的内部类Inner中有一个静态成员y,而Inner类却不是静态类。

(9)

选择题,写出错误答案错误的原因,用单行注释的方式。

1 class Demo{
2     int show(int a, int b){
3         return 0;
4     }
5 }
A.public int show(int a, int b){return 0;} //可以,覆盖。
B.private int show(int a, int b){return 0;} //不可以,权限不够。
C.private int show(int a, long b){return 0;} //可以,和父类不是一个函数。没有覆盖,相当于重载。
D.public short show(int a, int b){return 0;} //不可以,该函数不可以和给定函数出现在同一类或子父类中。
E.static int show(int a, int b){return 0;} //不可以,静态只能覆盖静态。

(10)

 1 //写出程序结果
 2 class Fu{
 3     int num = 4;
 4     void show(){
 5         System.out.println("showFu");
 6     }
 7 }
 8 
 9 class Zi extends Fu{
10     int num = 5;
11     void show(){
12         System.out.println("showZi");
13     }
14 }
15 
16 public class Demo{
17     public static void main(String[] args) {
18         Fu f = new Zi();
19         Zi z = new Zi();
20         System.out.println(f.num);
21         System.out.println(z.num);
22         f.show();
23         z.show();
24     }
25 }

输出结果:4 5 showZi showZi

(11)

 1 interface A{
 2     void show();
 3 }
 4 
 5 interface B{
 6     void add(int a, int b);
 7 }
 8 
 9 class C implements A, B{
10     //补全程序代码
11     private int sum = 0;
12     public void show(){
13         System.out.println(sum);
14     }
15     
16     public void add(int a, int b){
17         sum = a + b;
18     }
19 }
20 
21 public class Demo{
22     public static void main(String[] args) {
23         C c = new C();
24         c.add(4, 2);
25         c.show(); //通过该函数打印以上两个数的和
26     }
27 }

(12)

 1 //写出程序结果
 2 public class Demo{
 3     public static void main(String[] args) {
 4         try{
 5             showExce();
 6             System.out.println("A");
 7         }catch(Exception e){
 8             System.out.println("B");
 9         }finally{
10             System.out.println("C");
11         }
12         System.out.println("D");
13     }
14     public static void showExce() throws Exception{
15         throw new Exception();
16     }
17 }

输出结果:B C D

(13)

 1 //写出程序结果
 2 class Super{
 3     int i = 0;
 4     Super(){}
 5     public Super(String s){
 6         i = 1;
 7     }
 8 }
 9 
10 class Demo extends Super{
11     public Demo(String s){
12         i = 2;
13     }
14     public static void main(String[] args) {
15         Demo d = new Demo("yes");
16         System.out.println(d.i);
17     }
18 }

输出结果:2

(14)

 1 //写出程序结果
 2 class Super{
 3     public int get(){
 4         return 4;
 5     }
 6 }
 7 
 8 class Demo extends Super{
 9     public long get(){
10         return 5;
11     }
12     public static void main(String[] args) {
13         Super s = new Demo();
14         System.out.println(s.get());
15     }
16 }

编译失败。因为子父类中的get()方法没有被覆盖,子类调用时候不能明确返回的值是什么类型,所以这样的函数不能存在于子父类中。

(15)

 1 //写出程序结果
 2 public class Demo{
 3     public static void func() {
 4         try{
 5             throw new Exception();
 6             System.out.println("A");
 7         }catch(Exception e){
 8             System.out.println("B");
 9         }
10     }
11     public static void main(String[] args) {
12         try{
13             func();
14         }catch(Exception e){
15             System.out.println("C");
16         }
17         System.out.println("D");
18     }
19 }

编译失败。因为打印A的输出语句一定执行不到,throw单独存在时,后面不要写语句。就像return,break一样。

(16)

 1 public class Demo{
 2     public void func(){
 3         //位置1
 4     }
 5     class Inner{}
 6     public static void main(String[] args) {
 7         Demo d = new Demo();
 8         //位置2
 9     }
10 }
A.在位置1写 new Inner(); √ 外部类访问内部类。
B.在位置2写 new Inner(); × main函数是静态的,不能访问非静态类。
C.在位置2写 new d.Inner(); × 格式错误。把d还原为new Demo(),即new new Demo().Inner();
D.在位置2写 new Demo.Inner(); × 因为Inner不是静态的。

(17)

 1 //写出程序结果
 2 class Exc0 extends Exception{}
 3 class Exc1 extends Exc0{}
 4 
 5 public class Demo{
 6     public static void main(String[] args) {
 7         try{
 8             throw new Exc1();
 9         }catch(Exception e){
10             System.out.println("Exception");
11         }catch(Exc0 e){
12             System.out.println("Exc0");
13         }
14     }
15 }

编译失败。多个catch时,父类的catch要放在下面。

(18)

 1 interface Test{
 2     void func();
 3 }
 4 
 5 public class Demo{
 6     public static void main(String[] args) {
 7         //补足代码:(匿名内部类)
 8         new Demo().show(new Test(){
 9             public void func(){}
10         });
11         
12     }
13     void show(Test t){
14         t.func();
15     }
16 }

(19)

 1 //写出程序结果
 2 public class Demo{
 3     public static String output = "";
 4     public static void foo(int i){
 5         try{
 6             if(i == 1){
 7                 throw new Exception();
 8             }
 9             output += "1";
10         }catch(Exception e){
11             output += "2";
12             return;
13         }finally{
14             output += "3";
15         }
16         output += "4";
17     }
18     public static void main(String[] args) {
19         foo(0);
20         System.out.println(output);
21         foo(1);
22         System.out.println(output);
23     }
24 }

输出结果:134 13423

(20)

 1 //补足compare函数内的代码,不许添加其他函数
 2 class Circle{
 3     private static double PI = 3.14;
 4     private double radius;
 5     public Circle(double r){
 6         radius = r;
 7     }
 8     public static double compare(Circle[] cir){
 9         //程序代码,就是在求数组中的最大值
10         double maxR = cir[0].radius;
11         for(int i = 1; i < cir.length; i++){
12             if(cir[i].radius > maxR){
13                 maxR = cir[i].radius;
14             }
15         }
16         return maxR;
17     }
18 }
19 
20 public class Demo{
21     public static void main(String[] args) {
22         Circle cir[] = new Circle[3]; //创建了一个类类型数组
23         cir[0] = new Circle(1.0);
24         cir[1] = new Circle(2.0);
25         cir[2] = new Circle(4.0);
26         System.out.println("最大的半径值是:" + Circle.compare(cir));
27     }
28 }

(21)

 1 //写出程序结果
 2 public class Demo{
 3     private static int j = 0;
 4     private static boolean methodB(int k){
 5         j += k;
 6         return true;
 7     }
 8     public static void methodA(int i){
 9         boolean b;
10         b = i < 10 | methodB(4);
11         b = i < 10 || methodB(8);
12     }
13     public static void main(String[] args) {
14         methodA(0);
15         System.out.println(j);
16     }
17 }

输出结果:4。 因为|和&需要检查每一个条件的真伪。

原文地址:https://www.cnblogs.com/zhangtianq/p/6271272.html