Java编程思想思维导图

Java编程思想思维导图-Java开发者基础

Java编程思想思维导图第一章 对象导论异常处理:处理错误错误 ->置于编程语言中Java内置异常处理并强制使用对象的创建和生命周期C++Java追求最大执行速度编写时确定:存储空间和生命周期存储堆栈静态存储区存储堆的内存池逻辑假设容器集合泛型ListMapSet存储序列关联数组无重复集合向下转型 -->Object -->具体类型参数化类型单根继承结构好处保证所有对象具有某些功能极大简化参数传递容易实现垃圾回收伴随多态的可互换对象特定类型 --> 父类对象函数调用Java编译器向上转型不能依赖特定类型的代码前期绑定后期绑定非面向对象编程运行代码的绝对地址面向对象编程编译器-->确保调用方法的存在运行时-->计算代码的地址how?动态绑定会默认的对象中存储信息-->计算方法地址C++需要virtual关键字“是一个”与“像是一个”的关系是一个像一个继承至覆盖父类在子类中添加新的接口元素纯粹替代继承父类和子类差异直接在子类加方法覆盖方法复用具体实现组合继承现有类-->新的类极大的灵活性编译器 -->继承类 -->编译时的限制被隐藏的具体实现访问控制关键字让客户端程序员无法触及他们不应该触及的部分允许类库设计者改变内部分工作方式publicprotecteddefaultprivate任何类都可以访问仅继承的类可以访问仅同包目录下的类可以访问仅自己能访问每个对象都提供服务把对象想象成‘服务提供者’开发理解程序提高内聚性,不试图做更多的事每个对象一个接口接口问题空间元素<-->解空间元素确定某一特定对象,所能发出的请求抽象过程汇编语音命令式语言只针对待解决问题建模底层轻微抽象C、BASIC对汇编的抽象解决问题时基于计算机的结构不会基于需要解决问题的结构世界某些特定视图面向对象OOPLISP所有问题最终都是列表APL所有问题都是算法形成的不能解决所有问题表示问题空间的元素不会受限于任何特定类型的问题第二章 一切都会对象用引用操控对象必须由你创建所有的对象创建新的类型:类遥控器(引用)-->电视机(对象)存储地点特例高精度数字Java中的数组寄存器堆栈常量存储非RAM存储处理器的寄存器--速度最快不能直接控制通用RAM中java对象引用通用的内存池Java对象程序代码内部ROM(只读存储器)流对象持久化对象基本类型BigIntegerBigDecimal自动初始化范围检查少量内存开销运行时下标检查类成员的基本数据类型初始化非类字段 -->不初始化特例:基本类型booleancharbyteshorintlongfloatdoublevoid永远不需要销毁对象第4章 控制执行流程恰好出现在迭代语句前continue继续当前的下一次循环break中断当前循环continue label继续循环→label处break label中断循环→label处第5章 初始化和清理用构造器确保初始化确保每个对象初始化调用构造器,是编译器的责任没有返回值不是返回值为voidthis关键字问题a.peel(1), b.peel(2)如何知道是a还是b调用的peel方法?答案this-所操作对象的引用作为第一个参数→peel()类似于Banana.peel(a, 1)作用清理:终结处理和垃圾回收“特殊”内存GC仅负责new出来的对象“本地方法”分配的内存,GC无法回收finalize()GC前,调用finalize()GC,回收对象内存说明对象可能不被垃圾回收垃圾回收只与内存有关绝对不能直接调用finalize()对象的创建过程首次创建Dog对象、访问Dog静态方法,Java解释器定位Dog.class载入Dog.class,静态初始化new Dog()时,在堆上分配空间存储空间清零基本类型→默认值引用→null执行字段定义处的初始化动作执行构造器初始化静态初始化static{}首次加载类时执行(即使未生成类对象)非静态初始化{}生成对象时执行,匿名内部类的初始化构造器(最后执行)枚举类型enum类→编译器行为特性toString()ordinal()特定enum常量的声明顺序values()按顺序生成数组第6章 访问控制权限为什么控制访问权限?1.使用户不触碰不该触碰的部分2.更改内部实现,不影响客户端程序员访问权限关键字publicprotected继承的类+同包的类default同包的类private类的访问权限可以publicdefault不可以(特例:内部类)privateprotected第7章 复用类如何复用?组合新类中,产生现有类的对象继承按照现有类型,进行复用调用导出类,先加载基类@Override确保覆盖,而非重载代理继承和组合的中庸之道成员对象→构造的类中(组合)在新类中暴露成员对象的所有方法(继承)在组合与继承之间选择组合显式:在新类中放置子对象复用具体实现,而非接口继承隐式:在新类中放置子对象新类→基类,复用接口向上转型新类是现有类的一种类型类接口可能丢失方法final关键字数据基本类型引用引用所指向的对象恒定不变指向对象的内容,可以更改参数无法改变参数所指向的对象方法防止继承类覆盖private方法隐式地为final的无法获取→无法覆盖无法被继承Java的final类基本类型的包装类字符串StringStringBuilderStringBuffer数学MathStrictMath系统SystemClass第8章 多态对比多态分离:做什么↔怎么做,消除类型间的耦合关系封装合并:特征↔行为,创建新的数据类型实现隐藏分离:接口↔实现,将细节私有化问题基类的引用,如何找到继承类的方法?答案编译器不知道对象的类型运行时判断对象的类型,找到正确的方法体准则继承:表达行为(方法)间的差异组合:状态(对象)上的变化第9章 接口关系普通类→抽象类→接口抽象类和抽象方法抽象方法仅有声明,没有方法体abstract void f()抽象类包含抽象方法的类编译器阻止实例化可以不包含抽象方法阻止创建实例重构工具公共方法→继承层次向上移动接口含义完全抽象的类没有任何方法体隐式:static, finalJava 5前,创建常量组的工具(enum)不能是“空final”可以被非常量表达式初始化所有实现了特定接口的类,看起来都像这样类与类之间的协议作用完全解耦“忽略”继承层次实现“多重继承”接口的组合为什么使用接口?1.能向上转型为多个基类型2.防止创建该类的对象接口与工厂工厂方法工厂对象→创建方法生成接口的某个实现的对象好处代码完全与接口的实现分离透明地将某个实现,替换成另一个实现第10章 内部类private内部类完全阻止依赖于类型的编码完全隐藏了实现细节无法访问不属于公共接口的方法在方法和作用域内的内部类为什么需要?实现接口,创建并返回引用创建类,不希望类公共可用作用域和普通变量一样匿名内部类说明返回值的生成,表示返回值的类的定义结合在一起!通过new表达式,自动向上转型为接口的引用类是匿名的,没有名字构造器无参有参特点扩展类or实现接口,不能两者兼备只能实现一个接口工厂方法使用匿名内部类嵌套类说明static 内部类对象×外围类对象不能从嵌套类的对象,访问非静态的外围类对象接口内部的类嵌套类→接口的一部分接口中的任何东西,都是public和static的好处创建公共代码,被所有不同实现共用为什么需要内部类入口内部类对象→访问外围类对象的所有成员内部类→进入外围类的窗口多重继承每个内部类,独立继承一个(接口的)实现外围类继承层次,对内部类无影响内部类允许继承多个非接口类型闭包与回调回调对象携带信息,在某一时刻调用初始对象控制框架图形用户接口 GUI事件驱动系统第11章 持有对象第12章 异常第13章 字符串发现错误编译阶段运行时好处提供一致的错误报告模型节省代码正常逻辑↔错误逻辑ThrowableErrorJVM报告系统错误Exception编译期检查RuntimeException运行时异常可忽略,防止代码臃肿try-catch-finallycatch仅处理匹配的catch子句派生类对象,可以匹配基类finally子句总会执行即使try中有return!基本异常构造器默认字符串参数用名称代表发生的问题根类ThrowableprintStackTrace()从方法调用处→异常抛出处的方法调用序列标准错误流栈底:第一个方法调用容器用途保存对象编译期×错误类型→容器Collection说明独立元素的序列槽内只有一个元素分类List按照插入顺序ArrayList√随机访问元素×中间插入和移除元素LinkedList√中间插入和移除元素×随机访问元素Stack后进先出 LIFOSet元素不能重复HashSet散列函数→查询速度快TreeSet红黑树→排序Queue先进先出 FIFO→并发编程PriorityQueueMap映射表:“键值对”对象槽内有两个对象:键和与之关联的值迭代器统一了对容器的访问方式只能单向移动foreach隐形包括迭代器按照插入顺序字符串String对象不可变StringBuilder非线程安全,可变StringBuffer线程安全格式化输出Formatter正则表达式其他语言\dJava\\d\\\\一个\第14章 类型信息类型信息Class对象→JVM类加载器常用方法printInfo()全限定类名getInterfaces()包含的接口getSuperclass()直接基类newInstance()创建类必须有默认构造器初始化对静态方法或非常数静态域的首次引用static final 不初始化构造器隐式为静态的泛化的Class引用Class类型判断x instanceof IntegerRTTI含义RunTime Type Info运行时,识别对象的类型(多态)编译时打开和检查.class文件好处代码只操纵基类的引用方便扩展程序反射运行时加载类磁盘中的文件网络中的一串字节java.lang.reflectFieldMethodinvoke调用Constructor动态代理中间人→额外的操作Java的动态代理动态创建代理动态处理代理方法的调用所有调用→单一的调用处理器代码耦合度,超过你的期望第15章 泛型引入原因多态方法的参数是接口但是必须满足特定的接口泛型更通用→某种不确定的类型(接口)参数化类型(容器类)泛型简单泛型指定容器要持有什么类型编译器→保证类型的正确性元组类库一次方法调用,返回多个对象一个对象→持有多个对象泛型接口生成器,创建对象的类泛型方法泛型参数列表→返回值前尽量使用泛型方法擦除在泛型代码内部,无法获得任何有关泛型参数类型的信息泛型→具体类型信息→被擦除边界泛型的参数类型→设置限制条件<T extends HasF>限制为HasF的类型子集<? super T>超类型通配符(参数是下界)某个特定类的任何基类<?>无界通配符第16章 数组为什么特殊?效率存储和随机访问对象引用序列简单的线性序列效率最高类型保存基本类型泛型之前的容器不能优先使用容器更多的功能编译期类型检查效率已经不是问题Arraysfill()填充各个位置System.arraycopy()复制数组比for循环快很多equals()比较整个数组元素个数对应位置的元素sort()排序算法基本类型快速排序引用类型稳定归并排序对象比较的方式java.lang.Comparable接口编写自己的Comparator比较当前对象<参数负值当前对象>参数正值binarySearch()排序数组→快速查找当前对=参数0第17章 容器深入研究填充容器Collections.nCopies()Collections.addAll()Set和存储顺序Set每个元素—唯一元素必须定义equals()HashSet元素必须定义hashCode()TreeSet保持次序的set,底层为树结构元素必须实现Comparable接口方法first()返回容器的第一个元素last()返回容器的最末一个元素subSet(from, to)Set的子集headSet(to)tailSet(from)≥from的Set子集LinkedHashSet内部使用链表维护插入的次序元素必须定义hashCode()<to的Set子集理解Map实现HashMap构造器(调整容器性能)容量负载因子TreeMap基于红黑树的实现方法firstKey()lastKey()subMap()fromKey()headMap()tailMap()LinkedHashMap取得顺序是插入顺序WeakHashMap“弱键”,允许释放映射所指向的对象如果映射外没有引用指向键,则键可以被GCConcurrentHashMap线程安全不涉及同步加锁IdentityHashMap性能散列码相对唯一,代表对象的int值将对象的某些信息转换而成散列Map,必须实现equals()和hashCode()覆盖equals(),总是同时覆盖hashCode()hashCode()不需要返回唯一的标识码equals()方法必须严格判断两个对象是否相同散列与散列码ObjecthashCode()使用对象的地址计算散列码equals()比较对象的地址equals()自反性x.equals(x)=true对称性y.equals(x)=true→x.equals(y)=true传递性x.equals(y)=true,y.equals(z)=true→x.equals(z)=true一致性无论比较对少次,结果都是一样的x!=null→x.equals(null)=false理解hashCode()目的用一个对象→查找另一个对象键对象→生成数字(散列码)→数组下标bucket:实际散列表的数组命名冲突equals()方法→线性查询put()针对键hashCode(),转换取模数组的对应位置null创建新的LinkedList非nulllist是否有相同元素有→替换value没有→添加到list末尾get()同put()覆盖hashCode()why?无论何时,对同一个对象调用hashCode()→相同值hashCode()→处理→桶位下标how?不能依赖易变的数据数据变化→不同散列码不能依赖具有唯一性的对象信息(this)Apache库自动生成HashMap性能因子容量桶位数初始容量创建时拥有的桶位数尺寸当前存储的项数负载因子尺寸/容量空表0半满表0.5>负载因子,容器自动增加容量,再散列构造器可以指定,默认0.75同步控制自动同步整个容器synchronizedList()快速报错防止多进程同时修改同一容器持有引用引用SoftReference内存敏感的高速缓存WeakReference规范映射,不影响GC回收对象的实例可以在程序多处同时使用,节省空间PhantomReference调度回收前的清理工作WeakHashMap保存WeakReferencevalue只保存一份实例→节省存储空间Java 1.0/1.1 的容器VectorHashtableStackBitSet第18章 Java I/O系统概述源端-接收端文件控制台网络连接通信方式顺序随机存取缓冲二进制按字符按行按字File类表示特定文件的名称一个目录下的一组文件的名称输入和输出有能力产出数据的数据源对象有能力接收数据的接收端对象Java输入InputStream或Reader派生read()输出OutputStream或Writer派生write()叠合多个对象→期望功能InputStream作用表示从不同数据源产生输入的类途径字节数组String对象文件管道Internet连接类型ByteArrayInputStream内存的缓冲区StringBufferInputStreamStringFileInputStream文件读取信息PipedInputStreamSequenceInputStream两个或多个InputStream合并为单一FilterInputStream抽象类OutputStream作用输出所要去往的目标目标字节数组文件管道类型ByteArrayOutputStream内存创建缓冲区所有送往“流”的数据,都放于此FileOutputStream信息写至文件PipedOutputStreamFilterOutputStream抽象类添加属性和接口FilterInputStream从InputStream读取数据DataInputStreamBufferedInputStreamLineNumberInputStreamPushbackInputStreamFilterOutputStream向OutputStream写入DataOutputStreamPrintStream格式化输出BufferedOutputStreamReader和WriterInputStream和OutputStream面向字节8位,byteReader和Writer面向字符兼容Unicode信息的来源和去处InputStreamReader适配器InputStreamReaderOutputStreamWriter适配器OutputStreamWriterFileInputStreamFileReaderFileOutputStreamFileWriterByteArrayInputStreamCharArrayReaderByteArrayOutputStreamCharArrayWriterPipedInputStreamPipedReaderPipedOutputStreamPipedWriterI/O流的典型使用缓冲输入文件基本的文件输出标准I/O标准输入System.in未加工的InputStream标准输出System.outprintStream对象标准错误System.errprintStream对象进程控制Java内部→其他操作系统程序OSExecute.command()传递command字符串新I/OJDK 1.4速度提高通道、缓冲器修改类FileInputStreamFileOutputStreamRandomAccessFile压缩属于InputStream和OutputStream继承层次压缩类库按字节方式,不是字符方式Java档案文件JARJava ARchive一组文件→单个压缩文件跨平台压缩,传输时间短向服务器发一次请求对象序列化意义创建对象,程序终止时,保存状态自动弥补操作系统的差异方法实现Serializable接口对象→字节序列字节序列→原来的对象轻量级持久化对象必须显式序列化显式反序列化支持特性远程方法调用RMI存活于其他计算机的对象像存活于本机一样Java Beans配置状态信息方法序列化创建OutputStream对象封装在ObjectOutputStream对象中调用writeObject()即可对象序列化反序列化将InputStream封装在ObjectInputStream内调用readObject()transient关键字特定子对象,不想Java序列化保存逐个字段关闭序列化只能和Serializable对象配合使用XML对象序列化限制仅是Java的解决方案只有Java程序能反序列化这种对象优点跨平台跨语言Preferenceskey-value数据集合基本类型字符串单个字符串长度8K应用存储和读取用户的偏好程序配置项的设置数据存储位置不是本地文件使用合适的系统资源Windows的注册表第19章 枚举类型简介具名的值的有限集合→新的类型作为常规的程序组件使用基本enum特性values()enum实例的数组ordinal()enum实例在声明时的次序从0开始name()实例声明的名字向enum添加新方法定义方法时,enum实例序列最后要加分号enum不能被继承,剩下就像普通类使用接口组织枚举在接口内部,创建实现该接口的枚举→枚举分组常量相关的方法为enum实例编写方法→不同的行为第20章 注解第21章 并发概述元数据、源代码文件结合在一起有关程序的额外信息优点减轻编写“样板”代码的负担更加干净易读的代码编译期类型检查内置注解@Override当前方法覆盖超类的方法@Deprecated使用该元素,会发出警告@SuppressWarnings关闭不当的编译期警告信息元注解专门负责创建新的注解@Target表示注解可以用在什么地方ElementTypeCONSTRUCTOR构造器声明FIELD域声明LOCAL_VARIABLE局部变量声明METHOD方法声明PACKAGE包声明PARAMETER参数声明TYPE类、接口(包括注解类型)或enum声明@Rectetion在什么级别保存注解信息RetentionPolicySOURCE注解被编译期丢弃CLASS注解在class文件中可用,但会被VM丢弃RUNTIMEVM运行期也保留注解可用通过反射机制读取注解信息@Documented注解包含在Javadoc中@Inherited允许子类继承父类中的注解提取注解已知实现类Class:类定义Constructor:构造器定义Field:累的成员变量定义Method:类的方法定义Package:类的包定义方法getAnnotation:返回元素上指定类型的注解,如果该类型注解不存在,则返回null。getAnnotations():返回该程序元素上存在的所有注解。isAnnotationPresent:判断该程序元素上是否包含指定类型的注解,存在则返回true,否则返回false.getDeclaredAnnotations():返回存在于此元素的所有注解注解处理器读取注解的工具并发的多面性并发方式进程操作系统级别进程相互隔离线程Java支持抢占式更快的执行多处理器、多个任务→提高吞吐量↑运行在单处理器上的程序性能阻塞基本的线程机制定义任务实现Runnable接口,编写run()方法Thread类Runnable对象→Thread构造器线程调度机制是非确定性的早期JDK不会频繁对时间切片使用Executor客户端和任务执行间的间接层允许管理异步执行的任务,无需显式管理线程的生命周期shutdown()防止新任务提交给Executor当前线程继续允许之前提交的所有任务newCachedThreadPool为每个任务创建一个线程newFixedThreadPool预先执行代价高昂的线程分配newSingleThreadExecutor多个任务将排队任务会顺序执行所有任务使用相同的线程序列化任务,不需要同步共享资源从任务中产生返回值Runnable不返回任何值实现Callable接口call()ExecutorService.submit()调用Future对象休眠sleep()InterruptedException优先级线程的重要性→调度器JDK 10个优先级Windows 7个且不固定只使用MAX_PRIORITYNORM_PRIORITYMIN_PRIORITY让步yield()后台(daemon)线程在后台提供通用服务不是程序中不可或缺的部分所有非后台线程结束后,会杀死进程的所有后台线程setDaemon()加入一个线程join()共享受限资源不正确地访问资源EvenChecker消费者任务IntGeneratorEvenGenerator解决共享资源竞争why你永远都不知道一个线程何时在运行对资源加锁序列化访问共享资源互斥量-mutexsynchronized流程检查锁是否可用获取锁执行代码释放锁特定对象所有方法共享一个锁每个类syn static 方法共享一个任务可以多次获得对象的锁同步控制EvenGenerator显式的Lock对象代码缺乏优雅性更加灵活更细粒度的控制原子性与易变性原子性原子操作不能被线程调度机制中断应用中的可视性对volatile域修改所有读操作能立刻看到修改long和double两个分离的32位操作字撕裂volatile告诉编译器,不要执行任何读取和写入操作的优化读取和写入直接针对内存,不被缓存反例原子类AtomicIntegerAtomicLongAtomicReferencecompareAndSet(exp, update)临界区同步方法内部的部分代码,不是整个方法synchronized指定某个对象,锁用来对花括号内的代码同步(互斥量是同步整个方法)ThreadLocal根除对变量的共享为相同变量的不同线程,创建不同存储状态↔线程代码终结任务在阻塞时终结线程状态new 新建Runnable 就绪Blocked 阻塞有某个条件阻止线程运行调度器忽略线程Dead 死亡进入阻塞状态调用sleep()调用wait()线程挂起等待某个输入/输出完成试图在某对象调用同步方法,但对象锁不可用中断interrupt()Executor-shutdownNow()Executor.submit()返回Future,可调用cancel()线程间的协作概述互斥-解决资源共享问题协作-多个任务一起工作,解决某个问题任务之间的握手wait()和notifyAll()wait()等待某个条件发生变化,这个变化由另一任务实现挂起线程,对象上的锁释放sleep()和yield()没有释放锁!将任务挂起,只有在notify()或notifyAll()才被唤醒notify()通知对象x众多等待同一个锁的任务,只有一个被唤醒错失的信号死锁生产者与消费者Chef生产者WaitPerson消费者MealRestaurant生产者-消费者与队列wait()和notifyAll()是低级的任务操作,每次交互都握手更高的抽象级别-同步队列BlockingQueue同一时刻只允许一个任务插入或删除元素任务间使用管道输入/输出PipedWriterPipedReader死锁哲学家就餐ChopstaicksPhilosopherDeadlockingDining死锁条件互斥条件任务的资源至少有一个是不能共享的(筷子)持有资源一个任务持有一个资源,等待另一个资源资源不能被任务抢占循环等待新类库中的构件CountDownLatch同步一个或多个任务,强制它们等待由其他任务执行的一组操作CyclicBarrier一组任务并行执行,在进行下一个步骤前等待,直至所有任务都完成所有的并行任务在栅栏处列队,一致地向前移动DelayQueue无界的BlockingQueue,放置实现了Delayed的接口对象对象只能在到期时才能从队列取走PriorityBlockingQueue优先级队列,具有可阻塞的读取操作Exchanger两个任务交换对象的栅栏性能调优免锁容器原理对容器的修改可以与读取操作同时发生,只要读取者只能看到完成修改的结果修改在容器数据结果的副本执行,在修改过程中不可视CopyOnWriteArrayListCopyOnWriteArraySetConcurrentHashMapConcurrentLinkedQueue乐观加锁保持数据未锁定状态ReadWriteLock优化不频繁写入,但多个任务经常读取的数据结构如果写锁被持有,任何读取者都不能访问总结线程好处轻量级的执行上下文切换(大约100条指令)进程需要上千条指令,并改变所有内存空间而线程只改变程序的执行序列和局部变量多线程缺点等待共享资源时,性能↓处理线程,额外CPU糟糕的程序设计,导致不必要的复杂度病态行为:竞争、死锁不同平台导致的不一致性<