- JVM是可运行Java字节码文件的虚拟计算机。所有平台上的JVM向编译器提供相同的编程接口,而编译器只需要面向虚拟机,生成虚拟机能理解的代码,然后由虚拟机来解释执行。
- 当使用Java编译器编译Java程序时,生成的是与平台无关的字节码,这些字节码不面向任何具体平台,它只面向JVM。不同平台上的JVM是不同的,但它们都提供了相同的接口。
- Java程序必须以类(class)的形式存在,类是Java程序的最小程序单位,所有的程序部分必须放在类定义里面。
- 如果类能被解释器直接解释执行,则这个类里必须包含main方法,而且main方法必须使用public static main来修饰,且main方法的形参必须是一个字符串数组。Main方法是Java程序的入口。
- Java程序源文件的后缀必须是.java,不能是其他文件后缀名。
- 如果Java程序源代码里面定义了一个public类,则该源文件的主文件名必须与该public类的类名相同,一个Java源文件里最多只能定义一个public类。
- 如果指定了CLASSPATH环境变量,一定不要忘记在CLASSPATH环境变量中增加一点(.),一点代表当前路径,用以强制Java解释器在当前路径搜索Java类。
- Java程序的内存分配和回收都是由JRE在后台自动进行的。JRE会负责回收那些不再使用的内存,这种机制被称为垃圾回收(Garbage Collection),通常JRE会提供一条超级线程来进行检测和控制,一般都是在CPU空闲或内存不足时自动进行垃圾回收,而程序员无法精确控制垃圾回收的时间和顺序。
- Java的堆内存是一个运行时数据区,用以保存类的实例(对象),Java虚拟机的堆内存中储存着正在运行的应用程序所建立的所有对象,这些对象不需要程序通过代码来显式地释放。一般来说,堆内存是由垃圾回收来负责的,所有JVM在实现都有一个由垃圾回收机制管理的堆内存。垃圾回收是一种动态存储管理即使,它自动地释放不再被程序引用的对象,按照特定的垃圾回收算法来实现内存资源的自动回收功能。
- 在C/C++中,对象所占的内存在程序结束运行之前一直被占用,被明确释放之前不能分配给其他对象;而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾。JVM的一个超级线程会自动释放该内存区。垃圾回收意味着程序不再需要的对象是“垃圾信息”,这些信息将被丢弃。
- 当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用。事实上,除了释放没用的对象,垃圾回收也可以清除内存记录碎片。由于创建对象和垃圾回收器释放丢弃对象所占的内存空间,内存会出现碎片。碎片是分配给对象的内存块之间的空闲内存区,碎片整理将所占用的堆内存移到堆的一端,JVM将整理出的内存分配给新的对象。
- 垃圾回收的一个潜在缺点是它的开销影响程序的性能。Java虚拟机必须跟踪程序中有用的对象,才可以确定哪些对象是无用的对象,并最终释放这些无用的对象。这个过程需要花费处理器的时间。其次是垃圾回收算法的不完备性,早先采用的某些垃圾回收算法不能保证100%收集到所有的废弃内存。
- 任何一种垃圾回收算法要做两件基本的事情:发现无用的对象;回收被无用对象占用的内存空间,使该空间可被程序再次使用
- 垃圾回收有一下几个特点
14.1 垃圾回收机制的工作目标是回收无用对象的内存空间,这些内存空间都是由JVM堆内存里的内存空间,垃圾回收只能回收内存资源,对其他物理资源,如数据库连接,磁盘IO等资源则无能为力
14.2 为了更快地让垃圾回收机制回收那些不再使用的对象,可以通过将该对象的引用变量设置为null,通过这种方式暗示垃圾回收机制可以回收该对象。
14.3 垃圾回收发生的不可预知性,虽然程序员可以通过调用对象的finalize()方法或System.gc()方法来建议系统进行垃圾回收,但这种调用仅仅是建议,依然不能精确控制垃圾回收机制执行 - 一个基本原则是:对于不再需要的对象,不要再引用它们。如果我们保持了对这些对象的饮用,垃圾回收机制暂时不会回收该对象,则会导致系统可用内存越来越少。
- Java程序的最小程序单位是类,整个Java’程序由一个一个的类组成。
- 面向对象方法具有三个基本特征:封装(Encapsulation)、继承(Inheritance)和多态(Polymorphism)。其中,继承是面向对象实现软件复用的重要手段,当子类继承父类后,子类作为一种特殊的父类,将直接获得父类的属性和方法;封装指的是将对象的实现细节隐藏起来,然后通过一些公用方法来暴露该对象的功能;多态指的是子类对象可以直接赋给父类变量,但运行时依然表现出子类的行为特征,这意味着同一个类型的对象在运行时可能表现出不同的行为特征。
- 对象是面向对象方法中最重要的概念,它的基本特点是:标识唯一性、分类性、多态性、封装性、模块独立性好。
- 在Java语言中,除了8个基本数据类型值之外,一切都是对象。对象具有状态,一个对象用数据值来描述它的状态
- 具有相同或相似性质的一组对象的抽象就是类,类是对一类事物描述,是抽象的、概念上的定义;对象是实际存在的该类事物的每个个体,因而也称实例(instance)。
- Java语言是一门强类型的语言,所有的变量必须先声明、后使用。
- Java语言是强类型语言,意思是每个变量和表达式都有一个在编译时就确定的类型,所以所有变量必须显式声明类型。
- 引用数据类型就是对一个对象的引用,对象包括实例和数组两种。
- 如果系统支持把某个基本类型的值直接赋给另一种基本类型的变量,则这种方式被称为自动类型转换。
- continue终止本次循环,接着开始下一次循环。而break则是完全终止循环。
- return的功能是结束一个方法。当一个方法执行到一个return语句时,这个方法将被结束。
- static修饰的成员不能访问没有static’修饰的成员。
- 构造器不能定义返回值类型,也不能事业void定义构造器没有返回值。
- 当一个对象被创建成功以后,这个对象将被保存在堆内存中,Java程序不允许直接访问堆内存中的对象,只能 该对象的引用操作该对象。
- 如果堆内存里的对象没有任何变量指向该对象,那么程序将无法访问该对象,这个对象也就变成了垃圾,Java的垃圾回收机制将会回收该对象,释放该对象所占的内存区。
- this关键字最大的作用就让类中一个方法,访问该类的另一个方法或属性。
- Java里面方法的传递方式只有一种:值传递,就是将实际参数值的副本(复制品)传入方法内,而参数本身不会受到任何影响。
- Java允许同一个类里定义多个同名方法,只要形参列表不同就可。如果同一个类中包含了两个或两个以上方法的方法名相同,但形参列表不同,则被称为方法重载。
- 当系统加载类或创建该类的实例时,系统自动为成员变量分配内存空间,并在分配内存空间后,自动为成员变量指定初始值。
- 封装指的是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问。
- 构造器是一个特殊的方法,勇于创建类的实例。
- 重载主要发生在同一个类的多个同名方法之间,而重写发生在子类和父类的同名方法之间。
- 系统在类初始化阶段执行静态初始化块,而不是在创建对象时才执行。因此静态初始化块总是比普通初始化块先执行。
- 所有Java对象都可以和字符串进行连接运算。
- 当使用==来判断两个变量是否想等时,如果2个变量是基本类型的变量,且都是数值型,则只要两个变量的值相等,使用==判断将返回true
- 对于两个引用类型的变量,必须它们指向同一个对象时,==判断才会返回true
- 类属性属于整个类,当系统第一次准备使用该类时,系统会为该类属性分配内存空间,类属性开始生效,直到该类被卸载,该类的类属性所占有的内存才被系统的垃圾回收机制回收。
- final修饰基本类型变量时,不能对基本类型变量重新赋值。但对于引用类型的变量而言,它保存的仅仅是一个引用,final只保证这个引用所引用的地址不会改变,即一直引用同一个对象,但这个对象完全可以发送改变。
- 抽象类必须使用abstract修饰符来修饰,抽象方法也必须使用abstract修饰符来修饰,抽象方法不能有方法体
- 接口里不能包含普通方法,接口里所有方法都是抽象方法
- 闭包(Closure)是一种能被调用的对象,它保存了创建它的作用域的信息
- 垃圾回收机制只负责回收堆内存中对象,不会回收任何物理资源
- Java的集合大致可以分为:Set,List和Map三种体系,其中Set代表无序、不可重复的集合;List代表有序、重复的集合;而Map代表具有映射关系的集合。新增加的Queue体系集合,代表一种队列集合。
- 集合类主要负责保存、盛装其他数据,因此集合类也被称为容器类。所有集合类都位于java.util包下
- 数组元素既可以是基本类型的值,也可以是对象;而集合里只能保存对象
- Iterator主要用于遍历Collection集合中的元素
- HashSet不是同步的,如果多个线程同时访问一个HashSet,如果有2条或者2条以上线程同时修改了HashSet集合时,必须通过代码保证其同步。集合元素值可以为null
- HashSet性能总是比TreeSet好。只有当需要一个保持排序的Set时,才应该使用TreeSet,否则都应该使用HashSet
- ArrayList是线程不安全的,Vector是线程安全的。
- Map的key和value都可以是任何引用类型的数据。Map的key不允许重复。
- Hashtable是一个线程安全的Map实现,但HashMap是线程不安全的实现。所以HashMap比Hashtable的性能高一点;但如果有多线程访问同一个Map对象时,使用Hashtable实现类会更好
- Hashtable不允许使用null作为key和value;但HashMap可以使用null作为key和value
- 在集合接口、类后增加尖括号,尖括号里放一个数据类型,即表明这个集合接口、集合类只能保存特定类型的对象。
- 泛型,就是允许在定义类、接口时指定类型形参,这个类型形参将在声明变量、创建对象时确定。
- Runtime类代表Java程序的运行时环境,每个Java程序都有一个与之对应的Runtime实例,应用程序通过该对象与其运行时环境相连
- String类是不可变类,即一旦一个String对象被创建以后,包含在这个对象中的字符序列是不可以改变的,直至这个对象被销毁
- StringBuffer对象则代表一个字符序列可变的字符串,可以调用它的toString方法将其转换为一个String对象
- StringBuffer是线程安全的,而StringBuilder则没有实现线程安全的功能,所以性能略高。
- 常量池指的是在编译期被确定、并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口中的常量,也包括字符串常量。
- Pattern对象是正则表达式编译后在内存中的表示形式,因此,正则表达式字符串必须先被编译为Patter对象,然后再利用该Pattern对象创建对应的Matcher对象。执行匹配所涉及的状态保留在Matcher对象中,多个Matcher对象可共享同一个Pattern对象
- Finally块用于回收在try’块里打开的物理资源,异常机制会保证finally块总被执行
- 如果执行try块里的业务逻辑代码时出现异常,系统自动生成一个异常对象,该异常对象被提交给Java运行时环境,这个过程被称为抛出(throw)异常
- 数据表是存储数据的逻辑单元,其中每一行称为一条记录,每一列称为一个字段。
- 为每一个数据表指定一个特殊列,该特殊列的值可以唯一标识此行的记录,则该特殊列称为主键列
- 不能在where字句中过滤组,where子句仅用于过滤行。过滤组必须使用having子句
- 不能在where子句中使用组函数,having子句才可使用组函数
- JDBC编程步骤
72.1 加载数据库驱动:class.forName(driverClasss);
72.2 通过DriverManager获取数据库连接:DriverManager.getConnection(String url, String user, String pass)
72.3 通过Connection对象创建Statement对象
72.4 使用Statement执行SQL语句
72.5 操作结果集
72.6 回收数据库资源,包括关闭ResultSet、Statement和Connection等资源 - 事务是由一步或几步数据库操作序列组成的逻辑执行单元,这系列操作要么全部执行,要么全部不执行
- @Override是用来指定方法重载的,它可以强制一个子类必须覆盖父类的方法。
- File类是java.io包下代表与平台无关的文件和目录,File不能访问文件内容本身。如果需要访问文件内容本身,则需要使用输入输出流。
- 字节流操作的最小数据单元是8位的字节,而字符流操作的最小数据单元是16位的字符
- 一个任务通常就是一个程序,每个运行中的程序就是一个进程。当一个程序运行时,内部可能包含了多个顺序执行流,每个顺序执行流就是一个线程。
- 多个进程可以在单个处理器上并发执行,多个进程之间不会互相影响。
- 线程是进程的组成部分,一个进程可以拥有多个线程,一个线程必须有一个父进程。线程可以拥有自己的堆栈、自己的程序计数器和自己的局部变量,但不再拥有系统资源,它与父进程的其他线程共享该进程所拥有的全部资源。
- 线程是独立运行的,线程的执行是抢占式的。
- 一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行。
- Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例。每条线程的作用是完成一定的任务,实际上就是执行一段程序流。
- 定义Thread类的子类,并重写该类的run方法,该run方法的方法体就是代表了线程需要完成的任务;创建Thread类子类的实例,用线程对象的start方法来启动该线程。
- 进行多线程编程时不要忘记了Java程序运行时默认的主线程,main方法的方法体就是主线程的线程执行体。
- 使用继承Thread类的方法创建线程类,多条线程之间无法共享线程类的实例变量。
- 采用实现Runnable接口方式的多线程,线程类只是实现了Runnable接口,还可以继承其他类。
- 在线程的生命周期中,它要经过新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)五种状态。
- 启动线程使用start方法,而不是run方法,永远不要调用线程对象的run方法。调用start方法来启动线程,系统会把该run方法3线程执行体来处理。
- 线程池在系统启动时即创建大量空闲的线程,程序将一个Runnable对象传递给线程池,线程池就会启动一条线程来执行该对象的run方法,当run方法执行结束后,该线程并不会死亡,而是再次返回线程池中称为空闲状态,等待执行下一个Runable对象的run方法。
- IP地址用于标识网络中的一个通信实体。
- 当我们调用Java命令运行某个Java程序时,该命令将会启动一条Java虚拟机进程,不管该Java程序有多么复杂,该程序启动了多少个线程,它们都处于该Java虚拟机进程里。
- 类加载器负责将.class文件加载到内存中,并为之生成对应的java.lang.Class对象。
《疯狂Java》读书笔记
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- Java引用的种类 1.对象在内存中的状态 对于JVM的垃圾回收机制来说,是否回收一个对象的标准在于:是否还有引用...