精华内容
参与话题
问答
  • java编程思想

    千次阅读 2019-03-02 23:27:13
    java编程思想 1.面向对象五大特性 java编程思想 1.面向对象五大特性 万物皆为对象 程序是对象的集合,它们通过发送消息来告知彼此所要做的 每个对象都有自己的由其他对象所构成的存储 每个对象都拥有其类型 ...

    目录

    java编程思想

    1.面向对象五大特性


    java编程思想

    1.面向对象五大特性

    • 万物皆为对象
    • 程序是对象的集合,它们通过发送消息来告知彼此所要做的
    • 每个对象都有自己的由其他对象所构成的存储
    • 每个对象都拥有其类型
    • 某一特定类型的所有对象都可以接收同样的消息

    2.初始化与清理

    2.1 this关键字

    this关键字只能在方法内部使用,表示对''调用方法的那个对象''的引用.

    只有构造器能调用构造器,其他任何方法都不能调用构造器

    2.2 static关键字

    static方法就是没有this的方法

    static方法的内部不能调用非静态方法

    3.访问权限控制

    public --所有人都能访问

    protected--儿子能访问,包(package)内能访问

    默认(包访问权限)--包内能访问

    private--自己内部使用,外部不能访问

    4.复用类

    可以使用别人已经开发并调试好的类

    组合

    代理

    继承

    final:这是无法改变的

    5.多态

    向上转型

    向下转型

    6.访问权限控制

    7.复用类

    8.多态

    9.接口

    抽象类

    abstract:部分抽象

    interface:完全抽象

    10.内部类

    内部类

    匿名内部类

    11.持有对象

    容器

    集合:Collection,Map

    ArrayList,LinkedList,HashSet,TreeSet,LinkedHashSet,HashMap,TreeMap,LinkedHashMap

    12.通过异常处理错误

    基本异常

    捕获异常

    自定义异常

    13.字符串

    不可变String

    字符串拼接使用StringBuilder

    格式化输出:%s,%d,%f

    正则表达式很强大

    14.类型信息

    Class对象

    动态代理

    15.泛型

    擦除

    逆变

    无界通配符

    16.数组

    17.容器深入研究

    18.io

    19.枚举类型

    20.注解

    元数据

    4个注解专门负责注解的创建

    @Target

    @Retention

    @Documented

    @Inherited

    定义注解,并编写处理器来处理他们

    21.并发

    1.可以运行多个独立任务;

    2.必须考虑当这些任务关闭时,可能出现的所有问题;

    3.任务可能会在共享资源上彼此干涉.互斥(锁)是用来防止这种冲突的基本工具;

    4.如果任务设计得不够仔细,就有可能会死锁;

    展开全文
  • 本文将自己所搜集的几本java及相关的计算机电子版书籍分享出来,以便为各位下载...Java编程思想第四版完整中文高清版 Java并发编程实战 人月神话 点我合集下载 (电子版仅供预览及学习交流使用,下载后请24小时...

    本文将自己所搜集的几本java及相关的计算机电子版书籍分享出来,以便为各位下载。

    已经检查过链接的有效性,不保证所有链接一直有效,见谅。其中包括:

    Java核心技术 卷II 高级特性(原书第9版) 

    Java核心技术·卷1:基础知识(原书第9版)

    Java编程思想第四版完整中文高清版

    Java并发编程实战

    人月神话

     

    点我合集下载电子版仅供预览及学习交流使用,下载后请24小时内删除,支持正版

    Java核心技术·卷1:基础知识(原书第9版)

    作为一本力求讲解全部java基本知识的经典书籍,研读相关细节,所获心得颇多。从jdk的下载安装到部署应用程序;从数据类型控制流程到对象与类再到集合;从图形程序设计到Swing用户界面组件;从异常处理到多线程...每一块内容介绍的极其详细,显然有了这本书以后 再也不用google搜索java基础了。如果能够反复并从具体开发角度阅读会发现,此书不只是全面、具体而准确的介绍了java的相关概念和特性而已。而且深入讲解了Java语言的核心特性。诚如书名“Core Java”——Java语言核心内容   

                                           ----------------------引自豆瓣评论

    展开全文
  • Java编程思想(第4版) 配套源代码

    千次下载 热门讨论 2011-08-18 17:28:22
    Java编程思想(第4版) 配套源代码  本书是全球程序员必备图书《Java编程思想》的最新版本(《Java编程思想(英文影印版.第4版)》 )  本书曾获:  ·被china-pub会员评为“2007年我最喜爱的十大技术图书”之一  ·...
  • Java编程思想

    万次阅读 多人点赞 2018-08-18 19:30:40
    初读Java编程思想,由于我之前都是通过网络视频的方式来学习Java知识,所以此书初读起来有些晦涩难懂,但是我还是尽力去看,然后记下我初看时觉得对我有用的笔记和一些自己的理解。 第一章 对象导论 1.多态 在...

       初读Java编程思想,由于我之前都是通过网络视频的方式来学习Java知识,所以此书初读起来有些晦涩难懂,但是我还是尽力去看,然后记下我初看时觉得对我有用的笔记和一些自己的理解。

     

    第一章  对象导论

    1.多态
      在处理类型的层次结构时,把一个对象不当做它所属的特定类型来对待,而是将其当做其基类(父类)的对象来对待。这使得人们可以编写出不依赖于特定类型的代码。


    2.单继承
      单继承结构保证所有对象都具备某些功能,可以在每个对象上执行某些基本操作。


    3.参数化类型
      一个编译器可以自动定制作用于特定类型上的类,用于向下转型,如Circle是一种Shape类型,但是不知道某个Object是Circle还是Shape,此时就需要参数化类型,其实就是泛型。


    4.对象的创建和生命周期
      当处理完某个对象之后,系统某个其他部分可能还在处理它。java提供了被称为“垃圾回收器”的机制,它可以自动发现对象何时不再被使用,并继而销毁它。可以避免暗藏的内存泄露问题。


    5.并发编程
      并发:指应用能够交替执行不同的任务,例:吃完饭->喝水 喝完水->睡觉 一觉醒来->吃饭......
      并行:指应用能够同时执行不同的任务,例:吃饭的时候可以边吃饭边打电话,这两件事情可以同时执行。
      并行存在锁的概念,如两个相同线程并行访问到同一资源,该资源只能被一个线程使用,该资源会被锁定,被一个线程占用时,该任务锁定该项资源,完成任务,然后释放资源锁,使其它任务可以使用这项资源。

     

    第二章  一切都是对象

    1.对象存储到什么地方
      (1)寄存器
      (2)堆栈(RAM区):堆栈指针向下移动,分配新的内存,向上移动,则释放内存。
      (3)堆(RAM区):一种通用内存池。
       堆不同于堆栈的好处是:编译器不需要知道存储的数据在堆里存活多长时间。
       坏处:用堆进行存储分配和清理可能比用堆栈进行存储分配需要更多的时间。
      (4)常量存储
       直接存放在代码内部。
      (5)非RAM存储
       数据存活在程序之外,如磁盘。
      2.高精度数字
      BigInteger:支持任意精度的整数。
      BigDecimal:支持任何精度的定点数。
      3.static
      修饰代码块:先于构造器加载,并且只会加载一次,方法内没有this,全局方法,仅通过类本身来调用static方法。

     

    第三章  操作符

    第四章  控制执行流程

      第三、四两章我觉得很基础,所以没有笔记。

     

    第五章  初始化与清理

    1.构造器:这是一个在创建对象时被自动调用的特殊方法,确保初始化,java会在用户有能力操作对象之前自动调用相应的构造器,由编译器调用,与类名相同,无返回值。
    (1)不接受任何参数的构造器叫做默认构造器。
    (2)如果你没有定义构造器,编译器自动帮你创建默认构造器,但是如果你定义了构造器,编译器就不会再去创建默认构造器。

      例子:

    class Bird2{
       Bird2(int f){}
       Bird(double d){}
    }
    public class NoSynthesis{
        public static void main(String[] args){
           Bird2 b=new Bird2();//报错,没有默认构造器
           Bird2 b2=new Bird2(1);
           Bird2 b3=new Bird2(1.8);
          }
    }

    (3)除构造器之外,编译器禁止在其他任何方法中调用构造器。


    2.this:指出当前对象的引用  如 A a=new A();指出的就是引用a。


    3.垃圾回收器:垃圾回收器只会释放那些经由new分配的内存。


    4.finalize()方法:并非使用new获得的内存区域时,使用该方法释放内存,该区域主要指在java代码中调用了非java代码。也许会调用c的malloc()函数来分配空间,要释放空间得调用free(),但该方法是c、c++中才有的,所以在java中要使用finalize()。当垃圾回收器准备好释放对象占用的存储空间,将首先调用finalize()方法,并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。在做清理工作时,我们可以在finalize()里加入某种擦除功能,当垃圾回收发生时,finalize()得到调用,数据就会被擦除,要是垃圾回收没有发生,数据就会保留。
    (1)垃圾回收只与内存有关,也就是说使用垃圾回收器的唯一原因是为了回收程序不在使用的内存。无论是垃圾回收,还是终结,都不保证一定会发生。如果jvm并未面临内存耗尽的情形,它是不会浪费时间去执行垃圾回收以恢复内存的。


    5.垃圾回收器如何工作:
    (1)停止-复制
    先暂停程序的运行,然后将所有存活的对象从当前堆复制到另一堆,没有被复制的全是垃圾,当对象被复制到新堆时,它们是一个挨着一个的,所以新堆保持紧凑排列,然后就可以按像传送带一样的方法,每分配一个新对象,就往前移动一格,这样简单、直接地分配新空间了。当把对象从一处搬到另一处时,所有指向它的引用都必须修正。
    缺点:效率会降低。原因是,首先,得有两个堆,然后在这两个分离的堆之间来回捣腾,从而得维护比实际需要多一倍的空间。第二个问题,是复制,如果程序只有少量垃圾,或者没垃圾,垃圾回收器仍然会将所有内存自一处复制到另一处,这很浪费。
    (2)标记-清扫
    虚拟机进行检查,要是没有新垃圾产生,就会转向这一方式,该方式速度相当慢,但是当你知道只会产生少量垃圾甚至不会产生垃圾时,它的速度就很快了。
    该方式所依据的思路同样是从堆栈和静态存储区出发,遍历所有的引用,进而找出所有存活的对象,每当它找到一个存活对象,就会给对象设一个标记,这个过程中不会回收任何对象。只有全部标记工作完成的时候,清理才会开始。在清理过程中,没有标记的对象将会被释放,不会发生任何复制动作,所以剩下的堆空间是不连续的,垃圾回收器要是希望得到连续空间的话,就得重新整理剩下的对象。

    内存会分配较大的“块”,停止-复制要把所有存活对象复制到新堆,会造成大量内存复制行为,有了块之后垃圾回收器,就可以往废弃的块里拷贝对象了,这种好处就是先将空间分配好,执行时,就不需要现去分配空间,减少时间,典型的空间换时间。

    java实际垃圾清理是“自适应技术”:java虚拟机会进行监视,如果对象都很稳定,垃圾回收器的效率降低的话,就切换到“标记-清扫”方式,同样,java虚拟机会跟踪“标记-清扫”的效果,要是堆空间出现很多碎片,就会切换回“停止-复制”方式。

     

    6.自动初始化:如果没给基本类型的字段赋值,编译器会给其赋一个默认值,自动初始化会在构造器被调用之前执行。

     

    第六章  访问权限控制

    1.重构:即重写代码,以使得它更可读、更易理解、并因此而更具可维护性。

     

    第七章  复用类

    1.带参数的构造器:

    class Game{
      Game(int i){
         print("Game constructor");
     }
    }
    
    class BoarGame extends Game{
       BoarGame(int i){
            super(i)
            print("BoarGame  constructor");
       }
    }
    
    


      在继承中构造器的执行顺序:先父类构造器,然后子类构造器,上面代码要说明父类写的是带参数的构造器,所以没有默认构造器,子类必须在自身构造器中调用父类的带参构造器,因为子类会调用父类的默认构造器,但是此时父类没有默认构造器,所以不调用父类的带参构造器的话,会报错。

    2.名称屏蔽:
      如果java的基类拥有某个已被多次重载的方法名称,那么在子类中重新定义该方法名称不会屏蔽其在基类中的任何版本。就是说父类中有一个方法的多个重载,子类也重载了该方法,它不会屏蔽掉父类的多个重载。@Override指重写,如果你不想重载,加这个就不允许重载,只能重写。

    3.组合与继承:
      组合和继承都允许在新的类中放置子对象,组合是显示的这样做,而继承是隐式的做。

    4.protected:
      就类用户而言,这是private的,但对于任何继承与此类的子类或其他任何位于同一个包内的类来说,它是可以访问的。

    5.向上转型:
      举个例子:乐器A 、钢琴B  、B继承A ,B拥有A的所有方法,那么就可以说B是A类型的,再通俗就是父类引用指向子类对象。即  A a=new B() , a引用指向了一个B对象,表示B对象是A类型的。
      延伸:向下转型
      A a=new A();
      B b=(B)a ;      表示A对象是B类型

    6.final:
    (1)一个永不改变的编译时常量。
    (2)一个在运行时被初始化的值,而你不需要它被改变。
    final修饰方法
      把方法锁定,防止任何继承类修改它的含义,即确保在继承中父类的方法不会被子类覆盖。
    final修饰类
      你不允许被修饰的类有子类,即不能被继承。

     

    第八章  多态

    1.后期绑定:即多态实现机制,编译器一直不知道对象的类型,但是方法调用机制能找到正确的方法体,并加以调用。多态只能发生在方法调用时。当调用对象某个方法时,JVM查找该对象类的方法表以确定该方法的直接引用地址,有了地址后才真正调用该方法。   

    2.子类继承父类时,如果父类的一个方法私有,子类重写这个方法是不成功的,即使方法名一样也不能覆盖父类的这个方法,只能被当做一个新的方法去看待。

    3.只有普通的方法调用是多态的,如果直接访问某个域,这个域就将在编译期进行解析。如子类和父类中有两个相同名字的基本类型 如int a,子类不会覆盖父类的int a,而是分配了不同的存储空间,向上转型时,调用的就是父类的方法。
    如 :

    class Super{
              public int field=0;
              public int getField(){return field;}
    }
    
    class Sub extends Supoer{
              public int field=1;
              public int getField(){return field;}
              public int getSuperField(){return super.field;}
    }
        //Super sup=new Sub();
        //sup.field=0,sup.getField()=1
        //Sub sub=new Sub();
        //sub.field=1,sub.getField()=1,sub.getSuperField=0;
    

      为什么会这种结果:第一个是向上转型,调用的是Super这个类型的方法,所以field为0,sup.getField()=1是因为调用的是子类的方法,因为父类方法被子类重写了,当子类重写父类方法时,父类方法地址指向子类方法。

    4.构造器与多态:构造器相当于static方法,只不过该static声明是隐式的,子类调用构造器前,要先调用父类的构造器。

    5.继承与清理:一般清理由垃圾回收器自己去执行,但在某些必要条件下,要自己写清理方法,此时子类继承父类,父类中写了清理方法,但是子类存在特殊处理,所以重写父类清理方法,覆盖了父类清理,此时要注意,父类就不会被清理,由于是在子类中进行,父类的清理方法被覆盖掉了,所以在子类中没有执行父类的清理方法,所以一定要加上super的父类清理方法,否则父类的清理不会发生。

    6.构造器内部的多态方法的行为:在继承中,最好将父类直接放到子类中看,这样直观。

    class Glyph{
      void draw() { 
        print("G.draw()");
       }
      Glyph(){
       print("Glyph() before draw()");
       draw();
       print("Glyph() after draw()");
      }
    }
    
    class RoundGlyph extends Glyph{
       private int radius=1;
       RoundGlyph(int r){
        radius=r;
        print("RoundGlyph.RoundGlyph(),radius="+radius);
     }
        void draw(){
          print("RoundGlyph.draw,radius="+radius);
     }
    }
    
    public class PolyConstructors{
       public static void main(String[] args){  
         new RoundGlyph(5); 
     }
    }
    
         //输出 Glyph() before draw()
         //RoundGlyph.RoundGlyph(),radius=0
         //Glyph() after draw()
         //RoundGlyph.RoundGlyph(),radius=5

     

      这种输出结果的理解,先是调用父类构造方法,走到draw()时,要把父类放到在子类中结合看,可以看到draw()被重写了,所以调用的是子类的draw(),radius为0是由于在一切事物发生之前,将分配给对象的存储空间初始化二进制的0,即在调用父类构造前,先分配存储空间,初始化的值为0,执行完父类构造后,再给radius赋值为5。

     

    第九章  接口

    1.抽象类和抽象方法:包含抽象方法的类叫做抽象类,如果一个类包含一个或多个抽象方法,该类必须被限定为抽象的,否则编译器会报错。抽象类主要用来被继承,不能被实例化的类。

    2.使用接口的核心原因:
    (1)为了能够向上转型为多个基类型。
    (2)防止客户端程序员创建该类的对象,并确保这仅仅是建立一个接口。
    接口与抽象类之间的选择: 如果要创建不带任何方法定义和成员变量的基类,那么就应该选择接口,而非抽象类。

    3.通过继承来扩展接口:一个类只能继承一个基类,但能实现多个接口,接口可以继承接口,并且可以多继承。

    4.接口中的域:放入接口中的任何域都是自动static和final的。

     

    第十章  内部类

    1.链接到外部类:内部类自动拥有对其外围类所有成员的访问权,privte修饰的也可访问。
    理解:就是内部类能直接访问外部类的信息,但外围类不能直接访问内部类里的信息。

    2.使用.this与.new:创建一个内部类对象

    DotNew dn=new DotNew();
    DotNew.Inner dn1=dn.new Inner();


    3.内部类与向上转型:一个类里面,含有一个被private修饰的内部类,外部类不能访问这个内部类,除了内部类自己。

    4.在方法和作用域内的内部类:在一个作用域内的内部类,在作用域外,他是不可用的,除此之外,他与普通的类没有区别,作用域就是指{ }。

    5.匿名内部类:
    写法:

    return new A(){};
    

    在匿名内部类,他不可能有命名构造器,因为它根本没有名字。如果定义一个匿名内部类,并且希望它使用一个在其外部定义的对象,那么编译器会要求其参数引用是final的。

    6.嵌套类:如果不需要内部类对象与其外围类对象之间有联系,那么可以将内部类声明为static,这通常称为嵌套类。普通的内部类对象隐式的保存了一个引用,指向创建它的外围对象。
    嵌套类,意味着:
    (1)要创建嵌套类的对象,并不需要其外围类的对象
    (2)不能从嵌套类的对象中访问非静态的外围类对象
    如2中创建一个内部类对象,只需要

    Inner dn1=new Inner();

     

    7.接口内部的类:接口里可以放一个接口的实现类,该类实际就是嵌套类,因为接口自动public和static。

    8.为什么需要内部类:完成间接的多继承实现,即一个类只能继承一个父类,这时这个类只有两个可用类型,即本身和父类类型,但是如果还想有另外几个类型的话,就可以在子类中写一个方法,方法里写一个类。
    如 

    class Z extends D{
          E makeE() { 
         return new E(){};
     }
    }
    

    这时如果

    Z z=new Z();
    z.makeE();
    

    它z返回的类型就是E了。

    9.闭包与回调:闭包是一个可调用的对象,它记录了一些信息,这些信息来自于创建它的作用域。内部类是面向对象的闭包,它不仅包含外围类对象(创建内部类的作用域)的信息,还自动拥有一个指向外围类对象的引用,在此作用域内,内部类有权限操作所有的成员,包括private成员。

    10.内部类的继承:

    class WithInner{
       class Inner{
         }
    }
    
    public class InheritInner extends WithInner.Inner{
          InheritInner(WithInner wi){
            wi.super;
     }
    }

     

      这种继承内部类的类,它的构造器,必须传入一个内部类的外围类的对象的引用,然后必须在构造器中使用*.super这个语法。估计是规定,没有为啥。

     

    第十一章 持有对象

    1.泛型和类型安全的容器
    在<>可以放多个类型,不止一个。

    编译期错误:指将java文件转为二进制的class失败。
    运行时错误:转为二进制是成功的,在运行时出错。

    泛型里面也可以添加它的子类

    2.List

    List:线性顺序存储元素、元素可重复、可以存放null、可查找
    LinkedList:基于链表,中间插入删除快,按位置查找慢
    ArrayList:基于数组,中间插入删除慢、按位置查找快,原因是数组固定大小,插入时,要重新建一个数组

    3.迭代器
    Iterator: Iterator是一个迭代器接口,专门用来迭代各种Collection集合,包括Set集合和List集合。可以用来遍历不知道具体数目的list和set。
    (1)next()获得序列中的下一个元素
    (2)hashNext()检查序列中是否还有元素
    (3)remove()将迭代器新近返回的元素删除

    public static void main(String[] args)
        {
            List<String> list=new ArrayList<>();
            list.add("abc");
            list.add("edf");
            list.add("ghi");
            for(Iterator<String> it=list.iterator();it.hasNext();)
            {
                System.out.println(it.next());
            }
        }

     

    第十二章 通过异常处理错误

    1.异常说明
    Java提供相应的语法(强制使用这个语法),使你能以礼貌的方式告知客户端程序员某个方法可能会抛出的异常类型。这种做法的好处是,为异常先占个位子,以后就可以抛出这种异常而不用修改已有的代码。

    2.使用finally进行清理
    无论异常是否被抛出,finally子句总能被执行。

    3.finally用来做什么?
    析构函数是“当对象不再使用”会被调用的函数,java没有析构函数可供调用。java有垃圾回收机制,所以内存释放不是问题。当要把内存之外的资源恢复到它们的初始状态时,就要用到finally。

     

    第十四章 类型信息

    1.类字面常量
    就是static final先于static代码块。 

    2.泛化的class引用
    newInstance()也是用来创建新的对象,其与new()的区别是:
    newInstance()是弱类型,效率低,只能调用无参构造;new()是强类型,高效率,能调用任何public构造器 

    FancyToy fancytoy=ftClass.newInstance();
    Class<? super FancyToy> up = ftClass.getSuperclass();
    //下面这个会报错
    Class<Toy> up2 = ftClass.getSuperclass();
    //Toy在编译期就知道它是什么类型了,即Toy.class。getSuperclass()不仅仅只是“某个类,它是FancyToy”
    的超类。

     

    3.新的转型语法

    class Building{}
    class House extends Building{}
    public class ClassCasts{
      public static void main(String[] args){
            Building b=new House();
            Class<House> houseType = House.class;
            House h=houseType.cast(b);//相当于h=(House)b;
      }
    }

     

    4.类型转换前先做检查
    它的作用是用来判断,instanceof 左边对象是否为instanceof 右边类的实例。如x instanceof Dog 判断对象x是否属于Dog类。instanceof只可将其与命名类型进行比较,而不能与Class对象作比较。也可判断子类对象是否属于父类。

    5.instanceof与Class的等价性
    instanceof保持了类的概念,它指的是“你是这个类吗,或者你是这个类的派生类吗?”而如果用==比较实际的Class对象,就没有考虑继承——它或者是这个确切的类型,或者不是。

    6.类方法提取器
    getFields、getConstructors、getMethods获取的分别是一个class里面的public 变量、构造器、方法public Method[] getMethods()返回某个类的所有公用(public)方法包括其继承类的公用方法,当然也包括它所实现接口的方法。(包括继承的public)public Method[] getDeclaredMethods()对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。当然也包括它所实现接口的方法。(不包括继承的所有)

     


    第十五章 泛型

    1.泛型:

    参数化类型。这个术语的意思是适用许多许多类型和接口的区别就是,不用一定要接口定义的方法。

    2.理解了程序边界所在,你才能成为程序高手,因为只有知道了某个技术不能做到什么,你才能更好地做到所能做的(部分原因是,不必浪费时间在死胡同里乱转)。

    3.泛型的主要目的之一就是用来指定容器要持有什么类型的对象,而且由编译器来保证类型的正确性。T就是类型参数。

    4.泛型中能存入指定类型或者指定类型的子类,泛型与多态不冲突。

    5.元组:

    它是将一组对象直接打包存储于其中的一个单一对象,这个对象允许读取其中元素,但是不允许向其中存放新的对象(这个概念也称为数据传送对象或信使)。

    6.final,只要存在一次等于,就不准出现第二个等于,相同都不行。在对象被构造出来之后,声明为final的元素便不能被在赋予其他值

    下面这个程序,你可以使用first和second,但你却无法将其他值赋给它们

    public class TwoTuple<A,B> {
    	public final A first;
    	public final B second;
    	public TwoTuple(A a,B b){
    		first=a;
    		second=b;
    	}
    }

     

    7.泛型方法:
    public <T> void  f(T x){ }
    注意:当使用泛型类时,必须在创建对象的时候指定类型参数的值,而使用泛型方法的时候,通常不必指明参数类型,因为编译器会为我们找出具体的类型。这通常称为类型参数推断。

     

    第十九章  枚举

    1.enum:定义常量,相当于public static final。
    2.除了不能继承一个enum之外,我们基本上可以将enum看做一个常规的类。如果打算定义自己的方法,那么必须在enum实例序列的最后添加一个分号,同时必须先定义enum实例,即方法写在后面。感觉也相当于通配符的意义,便于代码清晰与维护。
    3.enum里面不能有重复,相当于set,但是不能存取。
    4.驱动代码:就是enum中的实例对象还可以写方法,如enum a{WINKEN{syso}}}。
    5.用于多路分发:就是如Number.plus(Number),或者match(new Item,new Item),Number是超类,这种不知道具体类型,多态可以动态绑定一个,但另一个就不行,这只是引出枚举的分发。

     

    第二十一章 并发

    1.并发的多面性:
    用并发解决的问题大体上可以分为“速度”和“设计可管理性”两种。速度:如果想让程序运行的很快,可以将其断开为多个片段,在单独的处理器上运行每个片段。使用并发编程最吸引人的一个原因就是要产生具有可响应的用户界面。

    java的线程机制是抢占式的,这表示调度机制会周期的中断线程,将上下文切换到另一个线程,从而为每个线程都提供时间片,使得每个线程都会分配到数量合理的时间去驱动它的任务。

    建议使用runnable接口,因为单继承,继承thread过于局限,接口还可以继承。

    start()方法被用来启动新创建的线程,而且start()内部 调用了run()方法,这和直接调用run()方法的效果不一样。当你调用run()方法的时候,只会是在原来的线程中调用,没有新的线程启动,start()方法才会启动新线程。

    2.基本线程机制
    一个线程就是在进程中的一个单一的顺序控制流。

    yield()(让步):使当前线程从执行状态(运行状态)变为可执行态(就绪状态)。cpu会从众多的可执行态里选择,也就是说,当前也就是刚刚的那个线程还是有可能会被再次执行到的,并不是说一定会执行其他线程而该线程在下一次中不会执行到了。

    当Runnable导出一个类时,它必须具有run()方法,但是这个方法并无特殊之处,他不会产生任何内在的线程能力,要实现线程行为,你必须显示地将一个任务附着到线程上。

    Executor(执行器):单个的Executor被用来创建和管理系统中的所有任务。(就是调用线程池)

    ExecutorService exec=Executors.newCachedThreadPool();
    exec.execute(new Liftoff());//Liftoff()是一个线程
    exec.shutdown();

    newCachedThreadPool:创建一个可缓存的线程池,若有需求它会回收空闲的线程进行使用,如果没有空闲的线程,则会创建新的线程。

    newFixedThreadPool:创建一个固定值的线程池,如果业务超出线程数量,那就排队,注意排队的时候是谁的线程结束了直接拿过来使用,但是线程充足的情况下,它会直接去拿新的线程。

    newScheduledThreadPool:是一个创建固定长度的线程池,支持定时和周期性执行。

    ScheduledExecutorService cachedThreadPool = Executors.newScheduledThreadPool(10);
    for(int i=0;i<10;i++){
        cachedThreadPool.scheduleAtFixedRate(new MyThread(i), 1,1000,TimeUnit.MILLISECONDS);
        //第二个参数表示线程第一次运行的初始时间,第三个参数是下一次间隔多长时间,第四个参数是时间单位:分、秒、时等
        cachedThreadPool.schedule(new MyThread(i), 1000,TimeUnit.MILLISECONDS);
        //第二个参数就是定时,跟上面第二个参数含义一样,只是它只执行一次
    }

    newSingleThreadExecutor:是创建一个单线程的线程池,线程数量为1,如果多个线程时,会排队,一个线程执行完再下一个,他所有的任务都是用这个线程来执行的,保证所有任务按照指定顺序执行。他还能保证当一个线程发生异常时,他会继续往下执行。

    实现线程的方式

    (1)继承Thread类创建线程

    (2)实现Runnable接口创建线程

    (3)实现Callable接口通过FutureTask包装器来创建Thread线程

    public class NewTest {
        public static void main(String[] args) {
            ExecutorService executor = Executors.newCachedThreadPool();
            Task task = new Task();//实现Callable接口的类
            FutureTask<Integer> futureTask = new FutureTask<Integer>(task);//将task由FutureTask包装器包装
            executor.submit(futureTask);//执行
            executor.shutdown();
            try {
                System.out.println("Task运行结果"+futureTask.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
    
        }
    }
    class Task implements Callable<Integer> {
        @Override
        public Integer call() throws Exception {
            int sum = 0;
            for(int i=0;i<100;i++)
                sum += i;
            return sum;
        }
    }

    (4)使用ExecutorService+Callable+Future实现有返回结果的线程

    public class NewTest {
        public static void main(String[] args) {
            ExecutorService executor = Executors.newCachedThreadPool();
            Task task = new Task();//实现Callable接口的类
            Future<Integer> future = executor.submit(task);//通过executor执行,返回值类型为Future
            executor.shutdown();
            try {
                System.out.println("Task运行结果"+future.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
    
        }
    }
    class Task implements Callable<Integer> {
        @Override
        public Integer call() throws Exception {
            int sum = 0;
            for(int i=0;i<100;i++)
                sum += i;
            return sum;
        }
    }

    FutureTask与Future区别:

    Future可以得到Callable的返回值。

    FutureTask既可以得到Callable的返回值,又可以作为Runnable被线程执行。

    3.后台线程
    是指在程序运行的时候在后台提供一种通用服务的线程,并且这种线程并不属于程序中不可或缺的部分。daemon.setDaemon(true)。

    4.加入一个线程
    如果某个线程在另一个线程t上调用t.join(),此线程将被挂起,直到目标线程t结束才恢复(即t.isAlive()返回为假)也可以在调用join()时带上一个超时参数,这样如果目标线程在这段时间到期时还没有结束的话,join()方法总能返回。 对join()方法的调用可以被中断,做法是在调用线程上调用interrupt()方法,这时需要用到try-catch子句。

    5.捕获异常
    会存在异常在try catch捕获不到的情况未捕获的异常通过uncaughtException来捕获。

    6.解决共享资源
    锁 synchronized  一个任务获得锁,外面的任务等待锁,但不是排队,而是根据抢占式,都有机会。

    7.临界区
    防止多个线程同时访问方法内部的部分代码而不是防止整个方法。通过这种方式分离出来的代码段被称为临界区。这也被称为同步控制块。


    8.线程本地存储
    防止任务在共享资源上产生冲突的第二种方式是根除对变量的共享(第一种应该是锁,对方法的共享)。ThreadLocal对象通常当做静态域存储,它保证不会出现竞争条件。

    ThreadLocal 是线程的局部变量, 是每一个线程所单独持有的,其他线程不能对其进行访问, 通常是类中的 private static 字段,是对该字段初始值的一个拷贝,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。

    当使用ThreadLocal维护变量的时候 为每一个使用该变量的线程提供一个独立的变量副本,即每个线程内部都会有一个该变量,这样同时多个线程访问该变量并不会彼此相互影响,因此他们使用的都是自己从内存中拷贝过来的变量的副本, 这样就不存在线程安全问题,也不会影响程序的执行性能。

    但是要注意,虽然ThreadLocal能够解决上面说的问题,但是由于在每个线程中都创建了副本,所以要考虑它对资源的消耗,比如内存的占用会比不使用ThreadLocal要大。
    (1)ThreadLocal.get: 获取ThreadLocal中当前线程共享变量的值。
    (2)ThreadLocal.set: 设置ThreadLocal中当前线程共享变量的值。
    (3)ThreadLocal.remove: 移除ThreadLocal中当前线程共享变量的值。
    (4)ThreadLocal.initialValue: ThreadLocal中的一个方法,默认返回null,重写此方法,可设置初始值。

    9.装饰性花园
    TimeUnit.SECONDS.sleep(5)线程等待五秒,TimeUnit.MILLISECONDS.sleep(5000)线程等待五秒。两者的时间单位不一样。内部都是Thread.sleep实现

    volatile,这就指示JVM,这个变量是不稳定的,每次使用它都到主存中进行读取主存即内存,其作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据。只要计算机在运行中,CPU就会把需要运算的数据调到内存中进行运算,当运算完成后CPU再将结果传送出来,内存的运行也决定了计算机的稳定运行。

    volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。(相当于每个线程访问的是最新的变量)(这个是公用,threadlocal是各自用各自复制的副本,private。本质区别就是,threadlocal是各自用各自,这个是共用,就是用的是最新的,我加1后,你得到的是加1后的)。

    10.线程状态
    一个线程可以出于以下四种状态之一
    (1)新建:当线程被创建时,它只会短暂的处于这种状态,此时他已经分配了必要的系统资源,并执行了初始化。此刻线程已经有资格获得cpu时间,之后调度器将把这个线程转变为可运行状态或阻塞状态。
    (2)就绪(感觉然后是运行)
    (3)阻塞:一个任务进入阻塞状态,可能有如下原因:
               1.通过调用sleep使线程进入休眠状态。
               2.调用wait(),join使线程挂起。
               3.任务在等待某个输入/输出完成。
               4.任务试图在某个对象上调用其同步控制方法,但是对象锁不可用(就是等待锁)。
    (4)死亡

    sleep与wait的区别:sleep使任务进入休眠状态,任务在指定的时间内不会运行,休眠时不释放锁。wait使线程挂起,直到线程得到了notify或notifyAll消息,线程才会进入就绪状态,挂起时释放资源锁。

    为什么sleep属于Thread,wait属于Object?
    其实两者都可以让线程暂停一段时间,但是本质的区别是一个线程的运行状态控制,一个是线程之间的通讯的问题。就是说sleep是线程里,wait是线程之间。

    11.中断:用来打断被阻塞的任务
    你能中断对sleep的调用,但是,你不能中断正在试图获取synchronized锁或者试图执行i/o操作的线程。它的两个例子,一个用的socket的close,另一个是nio通道,nio通道就可以中断i/o操作。

    注意,当你在线程上调用interrupt()时,中断发生的唯一时刻是在任务要进入阻塞操作中,或者已经在阻塞操作内部时。

    interrupted:检查中断状态,这不仅可以告诉你interrupt()是否被调用过,而且还可以清除中断状态。

    interrupt() 向当前调用者线程发出中断信号
    isinterrupted() 查看当前中断信号是true还是false
    interrupted() 是静态方法,查看当前中断信号是true还是false并且清除中断信号,顾名思义interrupted为已经处理中断信号。

    另外interruptedException时,他会清除掉interrupt信号。

    ReentrantLock上阻塞的任务具备可以被中断的能力。

    12.线程之间的协作
    调用sleep或者yield的时候,锁并没有被释放。当一个任务在方法里遇到了对wait的调用的时候,线程的执行被挂起,对象上的锁被释放。

    调用wait时就是在声明:我已经刚刚做完能做的所有事情,因此我要在这里等待,但是我希望其他的synchronized操作在条件适合的情况下能够执行。 其实就是说我做完了一部分工作,要等别人的工作完成,我才能继续工作,然后释放工具,希望其他需要而人能继续工作。

    可以通过notify、notifyAll、或者时间到期,从wait中恢复执行。

    13.
    notify:唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,必须等待相同的条件,将只唤醒等待特定锁的任务。则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。notifyall:唤醒在此对象监视器上等待的所有线程。

    错失的信号:就是抢占式的时候,线程先调用了notify的线程,后调用的wait线程,造成无限等待的死锁。


    14.死锁
    当以下四个条件同时满足时,就会发生死锁:
    1.互斥条件。任务使用的资源中至少有一个是不能共享的。
    2.至少有一个任务它必须持有一个资源且正在等待获取一个当前被识别的任务持有的资源。
    3.资源不能被抢占,任务必须把资源释放当作普通事件。
    4.必须有循环等待。这时,一个任务等待其他任务所持有的资源,后者又在等待另一个任务所持有的资源,这样一直下去,直到有一个任务在等待第一个任务所持有的资源,使得大家被锁住。

    死锁必须这四个条件同时满足,所以要解决死锁,只需破坏其中一个条件,最好破坏4。

    展开全文
  • Java编程思想笔记目录

    千次阅读 多人点赞 2020-10-24 11:05:22
    祝各位 程序?...但是吧,小名坐地铁或者走在大街上的时候,脑袋里总是会想一些有的没的,不排除会想一些Java基础的知识,时常联系不起来,就有可能别扭一整天。所以呢,把它发出来一方面是为了和大
    祝各位 程序🦍 节日快乐🎊

    在这里插入图片描述

    写在前面:
      前阵子,小名“偷偷地”发了一大批文章,是小名的一些读书笔记✍,那么为什么要把笔记发出来呢,嘻嘻,当然是小名的🧠不太灵光啦😣但是吧,小名坐地铁或者走在大街上的时候,脑袋里总是会想一些有的没的,不排除会想一些Java基础的知识,时常联系不起来,就有可能别扭一整天。所以呢,把它发出来一方面是为了和大家分享,作为这本书的一个能快速浏览的目录;另一方面,就是怕自己“钻牛角尖”的各种网上冲浪,也找不到书上的原版解释而别扭一天😂
    小名的《Java编程思想》学习笔记目录:

    注:每篇文章开头都会有一张脑图,图中的👉练习代码👈地址

    第一章 对象导论

    第二章 一切都是对象

    第三章 操作符

    第四章 控制执行流程

    第五章 初始化与清理

    第六章 访问权限控制

    第七章 复用类

    第八章 多态

    第九章 接口

    第十章 内部类

    第十一章 持有对象

    第十二章 通过异常处理错误

    第十三章 字符串

    第十四章 类型信息

    第十五章 泛型

    第十六章 数组

    第十七章 容器深入研究

    第十八章 Java I/O系统

    第十九章 枚举类型

    第二十章 注解

    第二十一章 并发


      不论现在你现在是在加班还是在家躺尸,也许是在刷小名的博客🤔,或许是在刷小名的博客😆,又或许是在刷小名的博客🤨(暗示三连~❤)都要记得,今天咱们过节呢🎉

      没对象的,咱也不要亏待了自己!午饭加个🍗,给生活比个✌

      有对象的,提醒🧑/👧今天你过节,要关注你的压力,为你的坚持点赞!留心收藏你们生活中的点点滴滴~

    在这里插入图片描述

    展开全文
  • Java程序员必读——领悟Java编程思想

    千次阅读 2012-12-11 10:20:37
    Java程序员必读——领悟Java编程思想     JAVA面试题解惑系列   Java易犯错误集锦 Java 语言从 C++派生而来,并借鉴了 Objective C Eiffel Smalltalk Mesa 和 Lisp 这些语言的一些特性。 当使用...
  • 关于编程思想和《java编程思想

    千次阅读 2006-05-16 01:25:00
    说实话,java编程思想是一本相当不错的书。说不好是介绍的泛泛还是细致,不过适合初学者对java的世界有一个全面的了解。话又说回来了,你要是对天生有像我一样的好奇心和怀疑精神,这本书不太适合你读,因为他没有给...
  • 81.JAVA编程思想——JAVA编程规则

    万次阅读 2016-05-10 22:56:36
    81.JAVA编程思想——JAVA编程规则 (1) 类名首字母应该大写。字段、方法以及对象(句柄)的首字母应小写。对于所有标识符,其中包含的所有单词都应紧靠在一起,而且大写中间单词的首字母。例如: ThisIsAClassName ...
  • java 编程思想

    2017-02-17 07:53:00
    java 编程思想java 编程思想java 编程思想java 编程思想java 编程思想java 编程思想java 编程思想java 编程思想java 编程思想java 编程思想java 编程思想java 编程思想java 编程思想java 编程思想java 编程思想 ...
  • java oop思想编程思想

    2009-03-02 13:31:00
    在栈空间定义局部变量;堆空间分配实例;调用方法的时候,给形参分配一空间,和局部变量等同,方法调用叫值传递; 方法执行完毕后,为该方法所配的内存空间也会清除; 基础类型的变量一块内存,引用类型的变量两块;...
  • Java编程思想.mobi

    热门讨论 2014-02-03 17:10:05
    Java编程思想.mobi 适合在kindle上看。
  • Java编程思想评注者序

    千次阅读 2011-06-28 16:55:00
    评注者序 与Thinking in Java的渊源学习Java的道路好比西天取经,Java就是要取得的真经,我们都是去往Java之路的圣徒。学习Java不仅要经历九九八十一难,更要理解Java这本圣经的精髓。大家都觉得Java之路不好走,...
  • Java编程思想 经典评注分享

    千次阅读 2011-07-14 16:33:35
    代码的格式规范必须遵守,包括命名、排版、注释、文件样式四个方面,这些样式目前有一些工具可以用来检查,可以通过集成在Eclipse...详细参见《高手真经之Java核心编程技术》(电子工业出版社出版)的第8章Java编码规
  • Java编程思想

    千次阅读 2019-05-18 15:46:01
    今天给大家推送一本Java经典书籍 《Java编程思想》 。 链接:https://pan.baidu.com/s/1-JN_5UyAkz4Mu41brqRDLQ 密码:y41t
  • Java编程思想 TXT版

    2018-11-07 22:51:53
    TXT格式java经典中的经典,可用作工具书和学习用书,字迹清晰,便于阅读。
  • Java编程思想高清完整Word版

    千次下载 热门讨论 2017-03-29 23:17:33
    本书赢得了全球程序员的广泛赞誉,即使是最晦涩的概念,在Bruce Eckel的文字亲和力和小而直接的编程示例面前也会化解于无形。从Java的基础语法到最高级特性(深入的面向对象概念、多线程、自动项目构建、单元测试和...
  • 再读《Java编程思想

    万次阅读 2017-04-21 11:27:49
    前段时间在豆瓣上无意间看到一个帖子“我为什么把thinking in java 读了10遍”,是11年的帖子,下面评论至今,各种声音都有,不过大多数还是佩服和支持的。我个人来讲也是非常支持的,而且也打算再读《Thinking in ...
  • Thinking in Java (Java 编程思想)

    万次阅读 多人点赞 2017-04-30 15:16:02
    Thinking in Java (Java 编程思想)本书来自网络,全科-不安分的码农整理成电子书,支持PDF,ePub,Mobi格式,方便大家下载阅读。
  • 初学java,经人推荐购买了java编程思想第四版,后发现看书时间不长,主要因为书本拿着不方便,后上网查找java编程思想4 PDF版,可是很多是一版和二版的PDF,因为要和书本一致,故找了很多,终于找到第四版。...
  • Java编程思想目录

    千次阅读 2019-04-28 10:11:00
    1、对象导论 2、一切都是对象 3、操作符 4、控制执行流程 5、初始化与清理 6、访问权限控制 7、复用类 8、多态 9、接口 ...18、java I/O系统 19、枚举类型 20、注解 21、并发 22、图形用户界面 ...
  • Java编程思想(第4版)

    千次下载 热门讨论 2014-07-02 09:21:52
    Java编程思想(第4版).pdf 真正的第四版,有好多内容是第三版,标题搞个第四版,有些猪头还一个劲的上传,误导人!因为我买了正版书第四版,不过是扫描版 的
  • java编程思想下载

    2014-02-13 16:28:40
    java编程思想下载 点击打开链接 目录 写在前面的话 引言 第1章 对象入门 第2章 一切都是对象 第3章 控制程序流程 第4章 初始化和清除 第5章 隐藏实施过程 第6章 类再生 第7章 多形性 第8章 对象...
  • 重读JAVA编程思想

    2013-12-11 10:08:00
    当年如猪八戒吃人生果般的读了java编程思想,只是知道这是本好书,但是具体细节,真是不知所云,很多都是工作中用到哪些,然后就翻《think in java 》和《core java》,有了这么多实际java编程经验之后,再翻这部著作...
  • Java编程思想 笔记

    千次阅读 2008-04-10 13:12:00
    第2章 一切都是对象1、用引用(reference)操纵对象在Java里一切都被视为对象,因此可采用单一固定的语法操纵数据。尽管一切都“看作”对象,但操纵的标识符实际上是对象的一个“引用”2、必须由你创建所有对象一旦...
  • 学习Java编程思想

    2005-06-02 17:59:00
    终于有时间把大名鼎鼎的《Java编程思想》通读了一遍,确实是一本好书。通过这次学习把Java系统的学习了一遍,以前会的都是工作中用到的那些,不全面。一直到参加了CA的招聘考试才知道自己的不足。自己总结了一个学习...
  • 35.JAVA编程思想——JAVA IO StreamTokenizer 尽管StreamTokenizer并不是从 InputStream或 OutputStream衍生的,但它只随同InputStream工作,所以十分恰当地包括在库的 IO部分中。 StreamTokenizer类用于将任何...
  • 71.JAVA编程思想——JAVA与CGI

    万次阅读 2016-05-08 21:27:20
    71.JAVA编程思想——JAVA与CGI Java 程序可向一个服务器发出一个CGI 请求,这与HTML 表单页没什么两样。而且和HTML 页一样,这个请求既可以设为GET(下载),亦可设为POST(上传)。除此以外,Java 程序还可拦截CGI...

空空如也

1 2 3 4 5 ... 20
收藏数 56,220
精华内容 22,488
关键字:

编程思想