A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© wisely 中级黑马   /  2014-7-19 21:50  /  1996 人查看  /  13 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 wisely 于 2014-7-23 16:12 编辑

前面的知识点太细太碎,容易遗漏,开贴记忆,方便自己,方便大家。
1、成员变量与局部变量
成员变量存在于堆中,作用于整个类中,随着对象的建立而存在,随着对象的消亡而消亡
局部变量存在于栈中,作用于方法内部或语句中。

2、静态代码块、构造代码块、构造函数
这三者都能进行初始化,运行优先级由高到低是:静态代码块,构造代码块,构造函数。
静态代码块,随着类的加载而运行,只运行一次。
构造代码块,随着对象的建立而运行,优先于构造方法。每次new对象都会运行一次。
构造函数,随着对象的建立而运行。   ——————————————
静态代码块,给类进行初始化。
构造代码块,给对象进行初始化。
构造方法,给对应对象进行初始化

3、this代表所在方法所属对象的引用,对象内的成员相互调用时,成员的前面都有一个隐藏的this关键字。

4、类名与构造方法名要一致。
如果类名前面有权限修饰符public,那么构造方法名前面也要有public。
5、当调用方法时,虚拟机会在栈中分配一块名为栈帧的内存空间,以供局部变量(包括基本类型与引用类型)使用。当方法调用结束后,虚拟机就会收回此内存。
6、匿名内部类其实就是一个匿名子类对象,不要被它的名字所迷惑,认为它是个类。
7、throw和throws的区别
① throw出现的方法内,throws出现在方法上
② throw后面跟的是异常对象,throws后面跟的是异常类,可以有多个,用逗号隔开。
8、RuntimeException如果在方法内抛出该异常,方法上可以不用声明,编译一样通过。
如果在函数上声明了该异常,调用者可以不用进行处理,编译一样通过。

9、异常的分类
① 编译时被检测的异常
② 编译时不被检测的异常(运行时异常,runtimeexception以及其子类)
10、异常在子父类覆盖中的体现:① 子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类,或不抛异常。
② 如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集
③ 如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。如果子类方法发生了异常,必须用try来处理。



点评

构造代码块先于构造函数的说法不准确。先进构造函数执行父类构造方法,然后是默认初始化、构造代码块和指定初始化,最后是构造函数的其他语句  发表于 2014-7-20 01:35

13 个回复

倒序浏览
关于this关键字

  1. class Person{
  2.         int age;
  3.         Person(int age){
  4.                 age=age;  //如果用关键词this,那么输入结果就会为5。
  5.                           //
  6.         }
  7.         void speak(){
  8.                 System.out.println("age="+age);
  9.         }
  10. }
  11. public class Sunday{
  12.         public static void main(String[] args){
  13.                 Person p=new Person(5);
  14.                 System.out.println(p.age);
  15.         }
  16. }

  17. 输出结果:0
复制代码
以前倒是没注意到这点,现在写上,以防忘了。


回复 使用道具 举报

  1. /*
  2. *this语句,用于构造器之间的相互调用。
  3. *小心类似死循环一样的调用。
  4. *一般函数不能调用构造函数
  5. */

  6. class Person{
  7.         private String name;
  8.         private int age;
  9.         Person(String name){
  10.                 this.name=name;  
  11.         }
  12.         Person(String name,int age){
  13.                 this(name);  //如果写成Person(name),就会报错,说找不到Person(String)方法
  14.                              //this语句只能放在第一行,不能放在其他位置,否则会报错,提示只能放在构造器语句的第一行。
  15.                              //放在其它行不安全。
  16.                 this.age=age;       
  17.         }
  18.         public String toString(){
  19.                 return name+":"+age;
  20.         }
  21.        
  22. }
  23. public class Sunday{
  24.         public static void main(String[] args){
  25.                 Person p=new Person("aaaa",10);
  26.                 System.out.println(p);
  27.         }
  28. }
复制代码











回复 使用道具 举报

main函数被玩儿坏了,毕老师太会玩儿了。
  1. class Sunday{
  2.         public static void main(String[] args){
  3.                 for(int i=0;i<args.length;i++){
  4.                         System.out.println(args[i]);
  5.                 }
  6.         }
  7. }

  8. class Demo{
  9.         public static void main(String[] args){
  10.                 String arr[]={"haha","huohuo","gaga","heihei","xixi"};
  11.                 Sunday.main(arr);
  12.         }
  13. }
复制代码



回复 使用道具 举报
构造代码块先于构造函数的说法不准确。先进构造函数执行父类构造方法,然后是默认初始化、构造代码块和指定初始化,最后是构造函数的其他语句。由于父类构造方法先于构造代码块,我有个感觉,其实构造代码块和指定初始化是被放入构造函数内部执行的。
回复 使用道具 举报
wisely 发表于 2014-7-20 01:19
main函数被玩儿坏了,毕老师太会玩儿了。

重载(overload)方法时,参数顺序不一样,仍旧不是一样的方法。


  1. class Demo{
  2.         public void show(int a,String str){
  3.                 System.out.println(a+":"+str);
  4.         }
  5.         public void show(String str,int a){
  6.                 System.out.println(str+":"+a);
  7.         }
  8. }

  9. public class Sunday{
  10.         public static void main(String[] args){
  11.                 Demo demo=new Demo();
  12.                 demo.show(10,"abc");
  13.                 demo.show("abc",10);
  14.         }
  15. }
复制代码
output:
10:abc
abc:10

回复 使用道具 举报
wisely 中级黑马 2014-7-21 20:33:10
7#
本帖最后由 wisely 于 2014-7-21 20:36 编辑
class Person{
        private String name;
        {
                System.out.println("我是构造代码块");
        }
        Person(){
                System.out.println("我是无参数构造函数");
        }
        Person(String name){
                System.out.println("我是有参构造函数");
        }
        static{
                System.out.println("我是静态代码块");
        }
        public static void show(){
                System.out.println("我是静态方法");
        }
}

public class Sunday{
        public static void main(String[] args) {

                Person p=null;   //这句代码并不会加载类,所以不会执行静态代码块。
                                           //用到类中的内容时,才会加载。
        }
}



回复 使用道具 举报
wisely 中级黑马 2014-7-21 21:02:56
8#
wisely 发表于 2014-7-21 20:33
class Person{
        private String name;
        {




  1. class Person{
  2.         private String name;
  3.         private int age;
  4.         private static String country="cn";
  5.         Person(String name,int age){
  6.                 this.name=name;
  7.                 this.age=age;
  8.         }
  9. }

  10. public class Sunday{
  11.         public static void main(String[] args){
  12.                 Person p=new Person("wamgda",20);
  13.         }
  14. }
复制代码
Person p=new Person("wangda",20)

该句代码的运行过程。
1、在栈内存中创建关于Person的引用p
2、因为new用到了Person.class虚拟机加载Person.class进内存
3、执行该类中的静态代码块,如果有的话,给Person类进行初始化
4、在堆内存中开辟空间,分配内存地址
5、在堆内存中建立对象的特有属性,并进行默认初始化。
6、对对象进行显式初始化
7、对对象进行构造代码块初始化
8、对对象进行对应构造方法的初始化
9、将内存地址赋给栈内存中的p。


回复 使用道具 举报
wisely 中级黑马 2014-7-22 23:15:33
9#
多态的主板示例




  1. interface PCI{
  2.         public abstract void open();
  3.         public abstract void close();
  4. }

  5. class MainBoard{
  6.         public void run(){
  7.                 System.out.println("mainboard run");
  8.         }
  9.         public void usePCI(PCI p){
  10.                 if(p!=null){
  11.                         p.open();
  12.                         p.close();
  13.                 }
  14.         }
  15. }

  16. class NetCard implements PCI{
  17.         public void open(){
  18.                 System.out.println("netcard open");
  19.         }
  20.         public void close(){
  21.                 System.out.println("netcard close");
  22.         }
  23. }

  24. class SoundCard implements PCI{
  25.         public void open(){
  26.                 System.out.println("soundcard open");
  27.         }
  28.         public void close(){
  29.                 System.out.println("soundcard close");
  30.         }
  31. }

  32. public class Sunday{
  33.         public static void main(String[] args){
  34.                 MainBoard mb=new MainBoard();
  35.                 mb.run();
  36.                 mb.usePCI(null);
  37.                 mb.usePCI(new NetCard());
  38.                 mb.usePCI(new SoundCard());
  39.         }       
  40. }
复制代码

程序本身不难,不过提到了接口的用法,特别不错。详见毕老师视频08-06
回复 使用道具 举报
看看         
回复 使用道具 举报
本帖最后由 wisely 于 2014-7-23 02:07 编辑

内部类定义在成员位置



  1. class Outer{
  2.         private int x=1;//想要让内部类访问到这个,需要将function中的x改成Outer.this.x
  3.                         //如果内部类没有与x重名的变量,那么省略Outer.this也行,前面会默认添加。
  4.         class Inner{
  5.                 int x=2;  //想要访问到Inner的成员变量x,function中的打印语句中的x需要改成this.x
  6.                 public void function(){
  7.                         int x=3;  
  8.                         System.out.println("Inner:"+this.x);
  9.                 }
  10.         }
  11.         void method(){
  12.                 Inner in=new Inner();
  13.                 in.function();
  14.         }
  15. }

  16. public class Sunday{
  17.         public static void main(String[] args){
  18.                 Outer out=new Outer();
  19.                 out.method();

  20.                 /*
  21.                 //直接访问内部类中的成员
  22.                 Outer.Inner in=new Outer().new Inner();   //内部类直接创建对象的方式
  23.                 in.function();
  24.                 */
  25.         }
  26. }
复制代码

内部类的访问规则:
1、内部类可以直接访问外部类中的成员,包括私有的成员。
        之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式 外部类名.this
2、外部类要访问内部类,必须建立内部类对象。

当内部类写在成员位置上时,可以加private修饰符。而外部类不可以。

一、当内部类被静态static修饰后,只能直接访问外部类中的static成员,出现了访问局限
    1、在外部其他类中,如何直接访问static内部类的非静态呢?
         new Outer.Inner().function()
    2、在外部其他类中,如何直接访问static内部类的静态呢?
         Outer.Inner.function()

二、当内部类中定义了静态static成员,该内部类必须是静态static的
三、当外部类中的静态方法访问内部类时,内部类也必须是静态的。


回复 使用道具 举报

内部类定义在局部

  1. /*
  2. 内部类定义在局部时,
  3. 1、不可以被成员修饰符修饰
  4. 2、可以直接访问外部类中的成员,因为还持有外部类中的引用。
  5.         但不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量。
  6.                 即便是方法method中的参数传递也必须是final,如method(final int a)
  7. */
  8. class Outer{
  9.         int x=1;
  10.         void method(final int a){  //此处的变量也必须是final
  11.                 //a++;        //加上这句就会挂掉,原因尚且不明
  12.                 final int y=2;//内部类想要访问y,必须定义成final
  13.                 class Inner{
  14.                         void function(){
  15.                                 System.out.println(Outer.this.x+":"+y+":"+a);
  16.                         }
  17.                 }
  18.                 new Inner().function();//想要运行function(),必须要new对象。
  19.         }
  20. }

  21. public class Sunday{
  22.         public static void main(String[] args){
  23.                 Outer out=new Outer();
  24.                 out.method(7);
  25.                 out.method(9);//虽然a为final,但它为局部变量,调用方法时进栈,而后出栈,不影响后面的调用
  26.                               //除非a是Outer类的成员变量。
  27.         }
  28. }
复制代码



回复 使用道具 举报
wisely 发表于 2014-7-23 02:06
内部类定义在局部
  1. "lisi".equals(name)与name.equals("lisi")的区别:
  2. 如果name=null,那么第一个可以运行,而第二个会抛出空指针异常
复制代码


回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马