⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 05. core java note.txt

📁 在达内培训java笔记
💻 TXT
📖 第 1 页 / 共 5 页
字号:
什么时候类加载
    第一次需要使用类信息时加载。
    类加载的原则:延迟加载,能不加载就不加载。

触发类加载的几种情况:
    (1)、调用静态成员时,会加载静态成员真正所在的类及其父类。
         通过子类调用父类的静态成员时,只会加载父类而不会加载子类。
    (2)、第一次 new 对象的时候 加载(第二次再 new 同一个类时,不需再加载)。 
    (3)、加载子类会先加载父类。
        注:如果静态属性有 final 修饰时,则不会加载,当成常量使用。
           例:public static final int a =123;
        但是如果上面的等式右值改成表达式(且该表达式在编译时不能确定其值)时则会加载类。
           例:public static final int a = math.PI
        如果访问的是类的公开静态常量,那么如果编译器在编译的时候能确定这个常量的值,就不会被加载;
        如果编译时不能确定其值的话,则运行时加载


类加载的顺序:
	1.加载静态成员/代码块:
	  先递归地加载父类的静态成员/代码块(Object的最先);再依次加载到本类的静态成员。
	  同一个类里的静态成员/代码块,按写代码的顺序加载。
	  如果其间调用静态方法,则调用时会先运行静态方法,再继续加载。同一个类里调用静态方法时,可以不理会写代码的顺序。
	  调用父类的静态成员,可以像调用自己的一样;但调用其子类的静态成员,必须使用“子类名.成员名”来调用。
	2.加载非静态成员/代码块:
	  先递归地加载父类的非静态成员/代码块(Object的最先);再依次加载到本类的非静态成员。
	  同一个类里的非静态成员/代码块,按写代码的顺序加载。同一个类里调用方法时,可以不理会写代码的顺序。
	  但调用属性时,必须注意加载顺序。一般编译不通过,如果能在加载前调用,值为默认初始值(如:null 或者 0)。
	  调用父类的非静态成员(private 除外),也可以像调用自己的一样。
	3.调用构造方法:
	  先递归地调用父类的构造方法(Object的最先);默认调用父类空参的,也可在第一行写明调用父类某个带参的。
	  再依次到本类的构造方法;构造方法内,也可在第一行写明调用某个本类其它的构造方法。
	注意:如果加载时遇到 override 的成员,可看作是所需创建的类型赋值给当前类型。
	  其调用按多态用法:只有非静态方法有多态;而静态方法、静态属性、非静态属性都没有多态。
	  假设子类override父类的所有成员,包括静态成员、非静态属性和非静态方法。
	  由于构造子类时会先构造父类;而构造父类时,其所用的静态成员和非静态属性是父类的,但非静态方法却是子类的;
	  由于构造父类时,子类并未加载;如果此时所调用的非静态方法里有成员,则这个成员是子类的,且非静态属性是默认初始值的。

成员,包括变量和方法
成员变量,包括实例变量和静态变量
    

final 修饰符
    (最终的、最后的)当final修饰时,不能被改变,不能被继承
    1.final 可以用来修饰类、属性和方法、局部变量。
    2.final 修饰一个属性时,该属性成为常量。
     (1)对于在构造方法中利用final进行赋值时,此时在构造之前系统设置的默认值相对于构造方法失效。
     (2)对于实例常量的赋值有两次机会
         在初始化的时候通过声明赋值
         在构造的时候(构造方法里)赋值
         注:不能在声明时赋值一次,在构造时再赋值一次。
         注意:当final修饰实例变量时,实例变量不会自动初始化为0;但必须给他赋值才能通过编译。
    3.final 修饰方法时,该方法成为一个不可覆盖的方法。这样可以保持方法的稳定性。
       如果一个方法前有修饰词private或static,则系统会自动在前面加上final。
       即 private 和 static 方法默认均为 final 方法。
    4.final 常常和 static、public 配合来修饰一个实例变量,表示为一个全类公有的公开静态常量。
       例: public static final int a = 33;
       在这种情况下属性虽然公开了,但由于是一个静态常量所以并不算破坏类的封装。
    5.final 修饰类时,此类不可被继承,即final类没有子类。
       一个 final 类中的所有方法默认全是final方法。
       final 不能修饰构造方法,构造方法不能被继承更谈不上被子类方法覆盖。

关于 final 的设计模式:不变模式
    1、不变模式:一个对象一旦产生就不可能再修改( string 就是典型的不变模式);
         通过不变模式可以做到对象共享;
    2、池化思想:用一个存储区域来存放一些公用资源以减少存储空间的开销。
         有池的类型:boolean,byte,int,short,long,char,(池范围在-127~128之间)
         (float,double 等小数没有池) 
         例:在String类中有个串池(在代码区)。
         池:堆里的一片独立空间。目的是拿空间换时间,让运算效率更高。
     (1)如果用Stirng str = “abc” 来创建一个对象时,则系统会先在“串池”中寻找有没有“abc”这个字符串
         如果有则直接将对象指向串池中对应的地址,如果没有则在串池中创建一个“abc”字符串。
         所以:String str1 = “abc”;
         String str2 = “abc”;
         Str1 == str2 返回值是ture;他们的地址是一样的。
           也就是说str1和str2都指向了代码空间中相同的一个地址,而这个地址空间保存就是是字符串"abc"
         字符串是不可改变的类型,所以可以共享。所以串池里不会有相同的两个字符串。

     (2)如果用String str = new String("abc")则直接开辟一块内存放"abc"这个字符串。
         所以上面这语句,创建两个"abc",一个在池,一个是对象
         String str2 = new String("abc");
         Str == str2 返回值是false;他们的地址是不一样的。
         即是说str和str2分别指向了堆空间中不同的两个地址,而这两个地址空间保存的都是字符串"abc"

StringBuffer 类(java.lang下的)。
    对于字符串连接
     String str=”1”+”2”+”3”+”4”;
         产生:
          12    123    1234
    这在串池中产生多余对象,而我们真正需要的只有最后一个对象,这种方式在时间和空间上都造成相当大的浪费。
    所以我们应该使用 StringBuffer(线程安全的) 或者 StringBuilder(线程不安全的)来解决
         解决方案:    
      StringBuffer sb = new StringBuffer(“1”);
      Sb.append(“2”);
      Sb.append(“3”);
      Sb.append(“4”);
      S = sb.toString();
    解决后的方案比解决前在运行的时间上快2个数量级。
StringBuilder (1.5版本后出现的)
    线程不安全的,在多线程并发时会出现问题。但仍是字符串合并的首选。
    运行效率比 StringBuffer 快一倍。


abstract 抽象
    1.可用来修饰类、方法
    2.abstract 修饰类时,则该类成为一个抽象类。
       抽象类不可生成对象(但可以有构造方法留给子类使用),必须被继承使用。
       抽象类可以声明,作为编译时类型,但不能作为运行时类型。
       abstract 永远不会和 private,static,final 同时出现。( 因为抽象必须被继承。)
    3.abstract 修饰方法时,则该方法成为一个抽象方法,抽象方法不能有实现;由子类覆盖后实现。
       比较:private void print(){};表示方法的空实现
       abstract void print();表示方法为抽象方法,没有实现
    4.抽象方法从某中意义上来说是制定了一个标准,父类并不实现,留给子类去实现。
       注:抽象类中不一定要有抽象方法,但有抽象方法的类一定是抽象类。
       抽象类可以有抽象方法和非抽象方法。实现抽象类的第一个具体类必须实现其所有抽象方法。
    5.关于抽象类的设计模式:模板方法
        灵活性和不变性

interface 接口
    1、定义:接口不是类,而是一组对类需求的描述,这些类要遵从接口描述的统一格式进行定义。
       定义一个接口用关键字 interface。
       例:public interface a{……}
    2、接口是一种特殊的抽象类。
       在一个接口中,所有的方法为公开、抽象的方法,所有的属性都是公开、静态、常量。
       所以接口中的所有属性可省略修饰符:public static final。也只能用这三个修饰符。
       接口中所有的方法可省略修饰符:public abstract。但这些都是默认存在的。
    3、一个类实现一个接口必须实现接口中所有的方法,否则其为一抽象类。而且实现类的方法需要 public
       实现接口用关键字 implements. 
       所谓实现一个接口就是实现接口中所有的方法。
       例:class Aimple implements A{……..};
    4、一个类除了继承另一个类外(且只能继承一个类),还可以实现多个接口(接口之间用逗号分割)。
       接口可以实现变相的多继承。
       例:class Aimple extends Arrylist implements A,B,C{…}
    5、不能用“new 接口名”来实例化一个接口,但可以声明一个接口。
    6、接口与接口之间可以多继承。
       例:interface face1 extends face2,face3{}
       接口的继承相当于接口的合并
    7、接口的作用
     (1)、间接实现多继承。
           用接口来实现多继承并不会增加类关系的复杂度。因为接口不是类,是在类的基础上的再次抽象。
           父类:主类型     接口:副类型
           典例:父亲(主)  和  老师(副)
     (2)、允许我们为一个类定义出混合类型。
     (3)、通过接口制定标准
            接      口:标准的定义  定义标准
            接口的调用者:标准的使用  使用标准
            接口的实现类:标准的实现  实现标准
        接口的回调:先有接口的使用者,再有接口的实现者,最后把接口的实现者的对象传到接口的使用者中,
                 并由接口的使用者通过接口来调用接口实现者的方法。
        例:sun公司提供一套访问数据库的接口(标准),java程序员访问数据库时针对数据库接口编程。
           接口由各个数据库厂商负责实现。
     (4)、解耦合作用:采用接口可以最大限度的做到弱耦合,将标准的实现者与标准的制定者隔离
         (例:我们通过JDBC接口来屏蔽底层数据库的差异)
    8、接口的编程设计原则
     (1)、尽量针对接口编程(能用接口就尽量用接口)
     (2)、接口隔离原则(用若干个小接口取代一个大接口)
           这样可以只暴露想暴露的方法,实现一个更高层次的封装。
    9、注意点:
     (1)、一个文件只能有一个 public 接口,且与文件名相同。
     (2)、在一个文件中不能同时定义一个 public 接口和一个 public 类。
     (3)、接口与实体类之间只有实现关系,没有继承关系;
          抽象类与类之间只有继承关系没有实现关系。接口与接口之间只有继承关系,且允许多继承。
     (4)、接口中可以不写 public,但在子类实现接口的过程中 public 不可省略。

接口 VS 抽象类
    1、接口中不能有具体的实现,但抽象类可以。
    2、一个类要实现一个接口必须实现其里面所有的方法,而抽象类不必。
    3、通过接口可以实现多继承,而抽象类做不到。
    4、接口不能有构造方法,而抽象类可以。
    5、实体类与接口之间只有实现关系,而实体类与抽象类只有继承关系
      抽象类与接口之间既有实现关系又有继承关系。
    6、接口中的方法默认都是公开抽象方法,属性默认都是公开静态常量,而抽象类不是。

修饰符的使用情况:
(Y表可用;不写表示不可用) 
    修饰符         类       属性        方法      局部变量(所有局部变量都不能用修饰符)
    public        Y         Y          Y         
    protected               Y          Y                                     
    (default)     Y         Y          Y                      
    private                 Y          Y        
    static                  Y          Y                           
    final         Y         Y          Y         Y
    abstract      Y                    Y

访问权限控制:
    修饰符      同一个类    同一个包  (不同包)子类  其他包
    public        Y         Y          Y       Y
    protected     Y         Y          Y   
    (default)     Y         Y            
    private       Y       


Object类
   1、object类是类层次结构的根类,他是所有类默认的父类。
   2、object类中的其中三个方法。
   (1)、finalize()
        当一个对象被垃圾收集的时候,最后会由JVM调用这个对象的finalize方法;
        注意:这个方法一般不用,也不能将释放资源的代码放在这个方法里;只有调用C程序时,才可能要用到

   (2)、toString()
        存放对象地址的哈希码值。
        返回一个对象的字符串表示形式。打印一个对象其实就是打印这个对象toString方法的返回值。
        可以覆盖类的toString()方法,从而打印我们需要的数据。 Public String toString(){……}

    (3)、equals(Object obj)
        用来判断对象的值是否相等。前提是覆盖了equals方法。Object类中的equals方法判断的依然是地址
        注意:String类已经覆盖了equals方法,所以能用equals来判断String对象的值是否相等。
下面是覆盖equals方法的标准流程:
/*************************************************************************/
  public boolean equals(Object obj){
    //第一步:现判断两个对象地址是否相等
    if(this == obj)  return   true;
    //第二步:如果参数是null的话直接返回false;
    if(obj == null)  return   false;
    //第三步:如果两个对象不是同一个类型直接返回false
    if (getClass() != obj.getClass()) return false;
    //?? if(!(this.getClass.getName().equals(o.getClass.getName())) return false;
    //第四步:将待比较对象强转成指定类型,然后自定义比较规则
       Student s = (Student) obj;
    if(s.name.equals(this.name)&&s.age==this.age) return true;
    else return false;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -