版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、目录1.原码、反码、补码11.1.原码11.2.反码11.3.补码11.4.负数的补码转换为十进制数22.char23.运算符23.1.移位运算符23.2.位运算符33.3.逻辑运算符34.流程控制34.1.switch34.2.break和continue45.方法45.1.构造方法45.2.方法重载46.this57.继承57.1.super57.2.多态(polymorphism)67.3.instanceof68.static79.final710.abstract811.类的加载811.1.触发类加载的几种情况811.2.类加载的顺序812.接口(interface)913.访问控制
2、1014.Object类1114.1.clone()1114.1.1.对象克隆过程1114.1.2.浅复制和深复制概念1214.2.finalize()1214.3.equals(Object obj)1214.4.toString()1215.String类及对象池1215.1.String a="hello"1315.2.String c=new String("hello");1316.StringBuffer和StringBuilder1317.主方法参数1418.方法的可变长参数1419.包装类1419.1.Number1519.2.自动封箱/
3、自动解封(Autoboxing/Unboxing)1519.3.对象池1520.内部类1620.1.意义1620.2.四种形式的内部类1620.2.1.静态内部类1620.2.2.成员内部类1720.2.3.局部内部类1820.2.4.匿名内部类1820.3.内部类的应用2021.集合框架(Collection Framework)2021.1.Iterator接口和Iterable接口2121.2.Connection接口和Connections类2121.2.1.java.util.Collection2121.2.2.java.util.Collections2121.3.List(列表
4、)接口2121.3.1.ArrayList2221.3.2.LinkedList2221.3.3.Vector2221.4.Set(集合)接口2221.4.1.HashSet2321.4.2.TreeSet2521.5.排序的两种办法2521.5.1.java.lang.Comparable(可比较的)2521.5.2.java.util.Comparator(比较器)2621.6.Map2621.6.1.HashMap2621.6.2.Hashtable2721.6.3.Hashtable下的子类Properties类2721.6.4.SortedMap接口下的TreeMap类2722.泛型
5、(Generic)2822.1.泛型特点2822.2.通配符2822.2.1.上限通配符:2822.2.2.下限通配符2922.2.3.总结:2922.3.运用3023.异常3023.1.异常处理基础3023.2.异常的类继承结构3023.3.常见的未检查异常3123.4.throw3123.5.自定义异常类3224.反射(Reflection)3324.1.反射需要用到的类3324.1.1.java.lang.Class3324.1.2.java.lang.reflect.Field3424.1.3.java.lang.Package3424.1.4.java.lang.relect.Mod
6、ifier3424.1.5.java.lang.reflect.Mothed3424.1.6.java.lang.reflect.Array3424.1.7.java.lang.reflect.Constructor3424.2.三种获得某个类的Class对象的方法3424.2.1.Class c=Class.forName("类名");3424.2.2.Class c=类名.class;3524.2.3.Class c=对象名.getClass();3524.3.所能探查出来的类的特征3524.4.通过反射生成一个类的实例3524.4.1.第一种方法3624.4.2.第二
7、种方法3625.File3625.1.构造方法3625.2.重点方法3725.3.目录3826.流3826.1.字节流3826.2.字符流4026.3.节点流(Node Stream):4126.4.过滤流 (Filter Stream)4126.5.ObjectInputStream和ObjectOutputStream4226.6.字节流转化成字符流的桥转换器4426.7.文本文件和二进制文件4627.线程4627.1.概念与原理4627.1.1.操作系统中线程和进程的概念4627.1.2.Java中的线程4727.1.3.Java中的线程模型4727.1.4.一些常见问题4727.2.线
8、程状态的转换4827.2.1.线程的七种状态4827.2.2.阻止线程执行5027.3.线程的同步与锁5127.3.1.同步和锁定5127.3.2.静态方法同步5627.3.3.如果线程不能获得锁会怎么样5627.3.4.何时需要同步5727.3.5.线程安全类5727.3.6.线程死锁5827.3.7.线程同步小结5927.4.线程的交互6027.4.1.线程交互的基础知识6027.4.2.多个线程在等待一个对象锁时候使用notifyAll()6227.5.守护线程(后台服务线程)6327.6.并发协作-生产者消费者模型6427.7.volatile关键字6428.网络编程6528.1.TC
9、P Socket编程6528.1.1.ServerSocket6628.1.2.Socket6628.2.UDP Socket编程6728.2.1.DatagramSocket6728.2.2.DatagramPacket671. 原码、反码、补码1.1. 原码将最高位作为符号位(以0代表正,1代表负),其余各位代表数值本身的绝对值(以二进制表示)。为了简单起见,我们用1个字节来表示一个整数:+7的原码为:00000111-7的原码为:10000111问题:+0的原码为:00000000-0的原码为:100000001.2. 反码一个数如果为正,则它的反码与原码相同;一个数如果为负,则符号位为
10、1,其余各位是对原码取反。为了简单起见,我们用1个字节来表示一个整数:+7的反码为:00000111-7的反码为:11111000问题:+0的反码为:00000000-0的反码为:111111111.3. 补码利用溢出,我们可以将减法变成加法。对于十进制数,如果从9得到结果5,可以用减法:9-4=5;因为4+6=10,我们将6作为4的补数,将上式的减法改写为加法:9+6=15;去掉高位1(也就是减去10),得到结果5。对于16进制数,如果从C得到结果5,可以用减法:C-7=5;因为7+9=16,我们将9作为7的补数,将上式的减法改写为加法:C+9=15;去掉高位1(也就是减去16),得到结果5
11、。在计算机中,如果我们用1个字节表示一个数,一个字节有8位,超过8位就进1,在内存中情况为:1 00000000,进位1被丢弃。一个数如果为正,则它的原码、反码、补码相同;一个数如果为负,则符号位为1,其余各位是对原码取反,然后整个数加1。为了简单起见,我们用1个字节来表示一个整数。+7的补码为:00000111-7的补码为:111110011.4. 负数的补码转换为十进制数a、 先对各位取反;b、 将其转换为十进制数;c、 加上负号,再减去1。例如:11111010,最高位为1,是负数,先对各位取反得00000101,转换为十进制数得5,加上负号得-5,再减1得-6。2. charchar类
12、型(2字节)用于表示Unicode编码的字符单元;char类型用于表示单个字符,通常用来表示字符常量。例如:'A'是编码为65所对应的字符常量。Unicode编码单元可以表示为十六进制值,其范围从u0000到uffff。除了可以采用转义序列符u表示Unicode代码单元的编码之外,还有一些用于表示特殊字符的转义序列符。如:转义序列名称Unicode值b退格(Backspace)u0008t制表(Tab)u0009n换行(Linefeed)u000ar回车u000d”双引号(Double quote)u0022单引号(Single quote)u0027反斜杠(Backslash
13、)u005c尽管char不是整数,但在许多情况中你可以对它们进行运算操作就好像他们是整数一样,这允许你可以将2个字符相加,或对一个字符变量值进行增量操作。3. 运算符3.1. 移位运算符只能针对二进制数据(整数)<< 左移,左移一位相当于原来的数乘二,大于32位的话高出的位就不要了,如果移动的位数大于32的话java会自动把这个位数变为这个数对32求余的值;>> 右移,右移一位相当于除2取整,两位相当于连续除2取整而不是除4取整,看正数还是负数,正数右移的话高位补0,负数的话补1;>>> 无符号右移(算数右移),不考虑符号位,移进来的都补0。3.2.
14、位运算符& 按位与,两个数按位与,全部转换成二进制后按位比较,全为1才是1,其它是0,返回一个新的整数;| 按位或,两个数按位或,全部转换成二进制后按位比较,全为0才是0,其它是1,返回一个新的整数; 按位异或,两个数的二进制位数比较,相同结果为0,相异结果为1; 按位求反,把一个数二进制的每一位都反过来。3.3. 逻辑运算符&& 短路与,两边如果左边是假的话就不再判断右边的,直接返回假;| 短路或,两边如果有一个为真的就不再判断右边的,直接返回真;& 与,不管怎样两边都会判断,都为真才返回真;| 或,不管怎样两边都会判断,都为假才返回假。4. 流程控制4.1.
15、 switcha、 switch后括号中的值必须是int,byte,char,short,枚举类型的变量之一,其它类型的就不行了;b、 每个case后面的值必须是不相等的,而且必须是常量;c、 如果每个case冒号后面的语句执行完后没有break,还会继续执行后面case里的语句,所以在每个case的语句结束后加一个break;d、 多个case可以可并到一起,表示或的关系;e、 default代表如果和所有case后的值都不匹配,就执行这里的语句。无论default写哪都是最后执行的。public class Grade public static void main(String args
16、) Scanner sca = new Scanner(System.in);System.out.println("请输入一个百分数:");int s = sca.nextInt();if (s < 0 | s > 100) System.out.println("ERROR DATA:S");System.exit(0);/ 退出这个程序switch (s / 10) case 10:case 9:System.out.println("A");break;case 8:System.out.println("
17、;B");break;case 7:System.out.println("C");break;case 6:System.out.println("D");break;default:System.out.println("E");break;4.2. break和continuea、 break退出当前的循环体,在嵌套循环中,只退出当前的一层循环;b、 continue结束当前本次循环,继续进行下一轮的循环。可以说,只是本次忽略循环内后面的语句;c、 continue只能在循环体内用;d、 break可以用在任意代码块中
18、,表示退出当前程序块(配合标签使用,很好用)。5. 方法5.1. 构造方法每次在创建实例变量,对类中的所有变量都要初始化是很乏味的。如果在一个对象最初被创建时就把对它的设置做好,那样的话,程序将更简单并且更简明。因为对初始化的要求是共同的,Java允许对象在他们被创造时初始化自己。这种自动的初始化是通过使用构造方法来完成的。构造方法在对象创建时初始化。一旦定义了构造方法,在对象创建后,在new运算符完成前,构造方法立即自动调用。构造方法看起来有点奇怪,因为它没有任何返回值,即使是void型的值也不返回。这是因为一个类的构造方法内隐藏的类型是它自己类的类型。构造方法的任务就是初始化一个对象的内部
19、状态,以便使创建的实例变量能够完全初始化,可以被对象马上使用。5.2. 方法重载在Java中,同一个类中的2个或2个以上的方法可以有同一个名字,只要它们的参数声明不同即可。在这种情况下,该方法就被称为重载(overloaded)。当一个重载方法被调用时,Java用参数的类型和(或)数量来表明实际调用的重载方法的版本。因此,每个重载方法的参数的类型和(或)数量必须是不同的。当一个重载的方法被调用时,Java在调用方法的参数和方法的自变量之间寻找匹配。但是,这种匹配并不总是精确的。在一些情况下,Java的自动类型转换也适用于重载方法的自变量。例如: class OverloadDemo void
20、test(double a) System.out.println("Inside test(double) a: " + a); class Overload public static void main(String args) OverloadDemo ob = new OverloadDemo(); int i = 88; ob.test(i); OverloadDemo的这个版本没有定义test(int)。因此当在Overload内带整数参数调用test()时,找不到和它匹配的方法。但是,Java可以自动地将整数转换为double型,这种转换就可以解决这个问题。
21、因此,在test(int)找不到以后,Java将i扩大到double型,然后调用test(double)。当然,如果定义了test(int),当然先调用test(int)而不会调用test(double)。只有在找不到精确匹配时,Java的自动转换才会起作用。6. thisthis等价于当前对象,调用当前对象的属性或方法就用this.属性名,或this.方法名()。当前对象:指谁在调用当前这个方法和属性,谁就是当前对象。在定义类的时候是不存在当前对象的。在局部变量与外部变量同名的时候,为了区分,就要在外部变量的前面加一个this来表示这个变量是类的全局变量。7. 继承尽管子类包括超类的所有成员
22、,它不能访问超类中被声明成private的成员。子类的对象可以调用父类的一切公有的变量和方法,也可以扩展自己新的属性和方法,但是新扩展的部分父类的对象是无法调用的。7.1. super在子类的构造方法中调用父类的构造方法,并且super要放在第一行,不能与this一起用,主要用为在构造子类的时候给父类中定义的变量赋值:a、 任何子类的构造方法都会调用父类的构造方法:因为调用构造方法和创建一个对象是绑在一起的,而一个子类对象的一部分可以看做是父类对象,所以当创建一个子类对象时一定是先创建一个父类的对象,再在父类对象的基础上扩展(extends)成一个子类对象。注意:自始至终只创建了一个对象,因为
23、创建的那一个子类对象的一部分是父类对象(上帝想创造一个科学家,肯定是先创造一个人,在人的基础上进行教育培训等,最终变成一个科学家,而最初的人和最后的科学家其实是一个对象);b、 任何子类的构造方法的第一行必须是this(.)或super(.)的调用,如果程序员不写,则系统会隐含的调用super(),也就是说子类无论如何都会调用父类的构造方法,没写就调用父类的无参构造方法;c、 子类构造方法的第一行只能出现this(.),super(.)这两种情况,无论怎么调用,最终总能找到父类构造方法,否则造成死循环。因为如果子类的某个构造方法的第一行出现this(.),此时系统不会加上缺省的super()那
24、么this(.)会调用子类的其他构造方法,所以子类的构造方法之间开始调用,如果子类的所有的构造方法的第一行全都是this(.)那便构成了一个死循环。7.2. 多态(polymorphism)a、 对象的多态:一个对象多种形态。方法的重载和覆盖就是方法多态的一种体现;b、 对象多态的基础:子类对象可以当作父类对象来看,例如:Animal a=new Bird();c、 多态定理:如果我们把子类对象当作父类对象来看,那么就只能访问父类中已有定义的属性和方法(不能访问子类扩展的属性和方法)。如果子类覆盖了父类的方法,再把子类对象当作父类对象去调用该方法时,调用的是子类覆盖后的方法(对象的行为不可能因
25、为你把它当作什么来看而改变);d、 Animal a=new Bird()左边是编译时类型:在代码编译过程中,编译器把这个对象当作什么来看?(父类对象)。右边是运行时类型:在代码执行过程中,JVM把这个对象当作什么看?(子类对象)。左边是主观认为(我们把a当作什么看?),右边是客观存在(a实际是什么)。当你把鸟当动物看时,你知道它是动物,但你不知道它是鸟,所以你知道它会走会吃,但你不知道它会唱歌(相当于编译器把它当Animal),所以你不会试图去调用它的唱歌的方法,因为你根本就不知道它会唱歌。当你调用move()方法时,它会flying,因为它本质上还是个鸟,不会因为你把它当作动物而不会飞用走
26、的路。7.3. instanceof当发生多层次复杂的继承机构时,往往使程序员自己都搞不清楚最后这个对象到底是什么了,这时就需要提供一个方法来判断一下了。判断一个对象是不是某一个类型的实例,看这个对象能不能作为这个对象实例来看(看这个对象运行时的类型,即看这个对象的客观存在是什么)。8. static描述整体特征而不是个体特征的属性时,用静态修饰符;有时你希望定义一个类成员,使它的使用完全独立于该类的任何对象。通常情况下,类成员必须通过它的类的对象访问,但是可以创建这样一个成员,它能够被它自己使用,而不必引用特定的实例。成员的声明前面加上关键字static就能创建这样的成员。如果一个成员被声明
27、为static,它就能够在它的类的任何对象创建之前被访问,而不必引用任何对象。你可以将方法和变量都声明为static,static成员的最常见的例子是main(),因为在程序开始执行时必须调用main(),所以它被声明为static。声明为static的变量实质上就是全局变量,当声明一个对象时,并不产生static变量的拷贝,而是该类所有的实例变量共用同一个static变量。Ø 声明为static的方法有以下几条限制a、 它们仅能调用其他的static方法;b、 它们只能访问static数据;c、 它们不能以任何方式引用this或super。Ø 静态变量和非静态变量(实例变
28、量)的差别a、 空间分配时机:静态变量是在类加载的时候分配空间,非静态对象是在生成对象的时候分配空间;b、 空间分配方式:不管有多少对象静态变量只有一份(所有对象共享),非静态变量有多少对象就分配多少个空间;c、 访问方式:静态变量是:类名.属性,比如Animal.COUNT;非静态变量:对象名.属性,比如。Ø 静态方法和非静态方法的区别a、 静态方法是通过类名来调用,非静态方法是通过对象来调用;b、 静态方法中不能访问本类的非静态成员,但非静态方法可以访问静态成员;c、 静态方法不存在多态特性,也就是静态方法无法被子类覆盖,父类对象调用此方法还是父类的。Ø 静
29、态代码块a、 静态代码块会在类被加载时被系统自动执行;b、 一般可以在静态代码块中给静态属性赋值;c、 类的静态代码块只能有一个。9. finala、 声明为final的变量在实例中不占用内存;b、 一个final变量实质上是一个常数;c、 修饰属性时属性不可变,并且属性在声明的时候必须初始化,或者在构造方法中初始化一般与static一起用,一旦定义了,就不能再变了;d、 修饰方法时方法不能被覆盖;e、 修饰类是类不能被继承,表示最终的类,不能有子类;f、 修饰局部变量时局部变量不可变(常量)。10. abstracta、 用来修饰类和方法;b、 修饰类的话表示这个类是个抽象类,抽象类不能被实
30、例化(生成对象);c、 修饰方法的话表示这个方法是个抽象方法,抽象方法没有方法体;d、 如果一个类包含有一个抽象方法,那么这个类必须是抽象类;e、 如果一个类不包含抽象方法,那么该类也可以被定义成抽象类;f、 抽象类不能被实例化,但却可以定义引用;g、 抽象类一般需要实现-定义一个子类,并实现抽象方法;h、 抽象类也是有构造方法的,因为需要被子类调用;i、 子类必须实现父类的抽象方法;j、 abstract和final不能共同修饰一个类或方法;k、 例如:定义一个Animal类,就可以定义成抽象类,move()方法可以定义成抽象方法,当具体的子类继承Animal时,再覆盖move()方法,鸟飞
31、,鱼游.11. 类的加载11.1. 触发类加载的几种情况a、 调用静态成员时,会加载静态成员真正所在的类及其父类;b、 通过子类调用父类的静态成员时,只会加载父类而不会加载子类;c、 第一次new对象的时候加载(第二次再new同一个类时,不需再加载);d、 加载子类会先加载父类(覆盖父类方法时所抛出的异常不能超过父类定义的范围);e、 如果静态属性有final修饰时,则不会加载,当成常量使用,例如:public static final int a =123;但是如果上面的等式右值改成表达式(且该表达式在编译时不能确定其值)时则会加载类,例如:public static final int a
32、 = math.PIf、 如果访问的是类的公开静态常量,那么如果编译器在编译的时候能确定这个常量的值,就不会被加载,如果编译时不能确定其值的话,则运行时加载。11.2. 类加载的顺序Ø 加载静态成员/代码块先递归地加载父类的静态成员/代码块(Object的最先),再依次加载到本类的静态成员。同一个类里的静态成员/代码块,按写代码的顺序加载。如果其间调用静态方法,则调用时会先运行静态方法,再继续加载。同一个类里调用静态方法时,可以不理会写代码的顺序。调用父类的静态成员,可以像调用自己的一样,但调用其子类的静态成员,必须使用“子类名.成员名”来调用。Ø 加载非静态成员/代码块(
33、实例块在创建对象时才会被加载,而静态成员在不创建对象时可以加载)先递归地加载父类的非静态成员/代码块(Object的最先),再依次加载到本类的非静态成员。同一个类里的非静态成员/代码块,按写代码的顺序加载。同一个类里调用方法时,可以不理会写代码的顺序。但调用属性时,必须注意加载顺序。一般编译不通过,如果能在加载前调用,值为默认初始值(如:null或者0)。调用父类的非静态成员(private除外),也可以像调用自己的一样。Ø 调用构造方法先递归地调用父类的构造方法(Object的最先),默认调用父类空参的,也可在第一行写明调用父类某个带参的。再依次到本类的构造方法,构造方法内,也可在
34、第一行写明调用某个本类其它的构造方法。注意:如果加载时遇到override的成员,可看作是所需创建的类型赋值给当前类型。其调用按多态用法:只有非静态方法有多态;而静态方法、静态属性、非静态属性都没有多态。假设子类override父类的所有成员,包括静态成员、非静态属性和非静态方法。由于构造子类时会先构造父类,而构造父类时,其所用的静态成员和非静态属性是父类的,但非静态方法却是子类的,由于构造父类时,子类并未加载,如果此时所调用的非静态方法里有成员,则这个成员是子类的,且非静态属性是默认初始值的。1、加载父类静态成员/代码块2、加载子类静态成员/代码块3、加载父类非静态成员/代码块4、加载父类构
35、造方法5、加载子类非静态成员/代码块6、加载子类构造方法12. 接口(interface)a、 接口可以通过运用关键字extends被其他接口继承;b、 当一个类实现一个继承了另一个接口的接口时,它必须实现接口继承链表中定义的所有方法;c、 是一种抽象的数据类型,特殊的抽象类;d、 接口中的所有方法都是抽象方法,就算不写系统也会自动加上abstract,所以一般就省去不写了;e、 接口中所有的属性都是final static的(静态常量),就算不写系统也会自动加上,所以一般可以省去不写了;f、 接口也不能被实例化,但可以定义的接口的引用;g、 接口没有构造方法,接口的实现类在生成对象时不会调用
36、接口的构造方法,类的子类在生成对象时一定要调用父类的构造方法(所以子类长的像父类,却不像接口);h、 一个类只能继承一个父类,但是可以实现多个接口,用逗号隔开;i、 接口之间可以多继承;j、 接口=标准:把服务的使用者和服务的提供者分开,降低系统的耦合,有效的提高软件的可扩展性和可维护性;k、 接口声明中可以声明变量,它们一般是final和static型的,意思是它们的值不能通过实现类而改变,它们还必须以常量值初始化,如果接口本身定义成public,所有方法和变量都是public的。13. 访问控制访问控制(access control)访问指示符(access specifier)stati
37、cfinalabstractpublicprotected默认private顶层类NYYYNYN属性YYNYNYY方法YYYYYYY局部变量NYNNNNN成员式内部类YYYYYYY局部式内部类NYYNNNN14. Object类构造方法只有唯一的一个,并且无参。14.1. clone()protected Object clone() throws CloneNotSupportedException创建并返回一个当前对象的拷贝,得到和当前对象一模一样的对象。clone()方法满足:a、 对任何的对象x,都有x.clone()!=x;克隆对象与原对象不是同一个对象了;b、 对任何的对象x,都有
38、x.clone().getClass=x.getClass();克隆对象与原对象的类型一样;c、 如果对象x的equals方法定义恰当,那么x.clone().equals(x)应该成立。14.1.1. 对象克隆过程Ø 要让这个类实现java.lang.Cloneable接口Cloneable接口,指示Object.clone()方法可以合法地对该类实例进行按字段复制。如果在没有实现Cloneable接口的实例上调用Object的clone方法,则会导致抛出CloneNotSupportedException异常。按照惯例,实现此接口的类应该使用公共方法重写Object.clone(
39、它是受保护的)。注意,此接口不包含clone方法。因此,因为某个对象实现了此接口就克隆它是不可能的。即使clone方法是反射性调用的,也无法保证它将获得成功。Cloneable接口没有任何方法,像Cloneable这样的接口叫做标记接口,即标记这个类的实例可以调用clone方法,只是起到一个标记的作用。Ø 覆盖Object中的clone()方法,并将访问权限改为publicclone();方法的访问修饰符是protected,这意味着,在子类中直接去super.clone();是可以的,但是如果想在第三方类中去生成一个子类对象后再取调用clone()时就不可以了,所以这时就得在子类中
40、去覆盖Object的clone方法,并将访问控制修饰符改为public。如果只是希望浅复制,那么使用这样的代码就可以完成public Object clone() throws CloneNotSupportedException return super.clone();这段代码表示,覆盖Object中的clone方法,将访问控制修饰符改为public,然后再去调用Object的clone方法。clone方法有具体的实现步骤代码,这叫做是实现方法。因为clone方法涉及到底层数据的访问,一般的程序员是没有办法写出这些代码的,所以用这样的一个简单的步骤就可以达到clone的目的了。14.1.2
41、. 浅复制和深复制概念Ø 浅复制(浅克隆)被复制对象的所有变量都含有原来的对象的相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不是复制它所引用的对象。Ø 深复制(深克隆)被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。例如:一个Student对象包含ID,姓名,Teacher等属性。其中ID为基本类型,姓名为String类型,Teacher为一个Teacher对象。浅复制
42、只复制一个新的ID,而姓名和Teacher只复制地址。即,复制后的新对象姓名和Teacher仍然指向原先的Stuent的姓名和Teacher。而深复制会连同姓名和Teacher也同样复制出来,并且与原对象的地址不同,指向不同的对象。14.2. finalize()a、 构造方法负责对象创建后的初始化,finalize方法负责对象消亡时的资源释放;b、 finalize方法被垃圾收集器自动调用,而垃圾收集器有可能根本不执行,所以没有办法保证finalize方法一定执行。14.3. equals(Object obj)下面是Object中的equals方法源码: public boolean eq
43、uals(Object obj) return (this = obj); 14.4. toString()返回该对象的字符串表示。通常,toString 方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂的信息表达式。建议所有子类都重写此方法。Object 类的 toString 方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“”和此对象哈希码的无符号十六进制表示组成。换句话说,该方法返回一个字符串,它的值等于:getClass().getName() + '' + Integer.toHexString(hashCode()
44、15. String类及对象池在JDK5.0里面,Java虚拟机在启动的时候会实例化9个对象池,这9个对象池分别用来存储8种基本类型的包装类对象和String对象。对象池的存在是为了避免频繁的创建和销毁对象而影响系统性能。对象池是独立于栈空间和堆空间的,保存着指向一些对象的首地址。15.1. String a="hello"首先把hello这个对象创建出来,并保存在堆中。然后对象池会保存一个指向hello的首地址。如果a是某个方法内的局部变量,那么也会在栈中将hello的首地址保存在a中。如果a的地址值被赋为null,也就是a不再指向hello了,此时hello并没有成为垃
45、圾,因为对象池中始终保存了hello的首地址指向hello。而对象池中的那些地址值,程序员是不能直接管理的,那是由JVM才能直接管理的。下次如果需要String b="hello"创建"hello"对象,那么b会去对象池中找那些地址值,如果找到了指向hello对象的地址,那么会将这个地址直接赋给b。如果没有与之匹配的,才会创建新的对象,并同样将这个对象的首地址保存在对象池中。15.2. String c=new String("hello");系统会直接在堆空间中创建一个新的hello对象,而不会去对象池中找,而且这样创建的新的hel
46、lo对象也不会保存在对象池去。注意注意:String s=new String("hello");直接只有这条语句的时候,这里的hello作为一个参数传给String,而此时没有hello这个对象,那么:首先会创建一个hello对象,并且将这个hello对象的首地址保存在对象池中,然后将这个hello对象作为参数传给String,此时又new了一个新hello对象,而s中保存的是新的hello对象的首地址。所以只有这条语句的时候,实际上是创建了两个hello对象。16. StringBuffer和StringBuilder当我们需要对字符串频繁的进行修改时,最好不要用Str
47、ing类,因为那会产生很多垃圾,降低系统效率。在java.lang包下,有两个StringBuffer和StringBuilder类,是更好的选择。因为用它们new出来的字符出对象是可以更改的,而且会在原字符串的基础上进行更改,而不会向String那样创建新的字符串对象,所以避免了垃圾的产生。而StringBuffer和StringBuilder的唯一区别是:StringBuffer是线程安全的(Thread-safe)字符序列;StringBuider是线程不安全的字符序列。主要关注点:一是构造方法,二是众多重载的append(追加)和insert(插入)方法。public class St
48、ringBufferTest public static void main(String args) StringBuffer s=new StringBuffer();for(char c='A'c<='Z'c+)s.append(c);System.out.println(s.toString();17. 主方法参数java 类名 命令后面还可以给一些主方法的参数,这些参数都被系统当作字符串放到main方法声明的参数String args中,如果输入多个参数的话就以空格为分隔符依次把每个参数放入args数组。如果不传参数的话args就是一个0个元素的
49、数组。在eclipse中给主方法传参数:右键run asàrun configurationsàMain class要是现在要运行的类,如果不是就要search找到àargumentsà在上面的栏中就是给main方法传的参数,填上参数àapplyàRun。在把这些参数传给主方法之前,JVM会先对这些参数做一个包装,把它们先包装成一个字符串数组之后再传给主方法。所以主方法的参数是String args。18. 方法的可变长参数其实当我们把不同长度的参数传给方法时,编译器会对这些参数做一个包装,把它们包装成一个数组之后再传给方法,所以方法
50、得到的还是一个数组。所以方法的可变长参数实际上是数组的一种特殊的表现形式。在定义方法的时候知道要传的参数的类型,但是参数的数量不固定的时候就用可变长参数,可变长参数类型的写法,例如:public static void m(String. strs).上面的参数类型在String后面多了.,这样在调用方法传参数的时候就可以传多个参数或者一个参数,也可以不传参数,但参数必须都为String类型的,如果要传其它类型的时候在定义的时候改成其它类型,然后在类型后面加上.就可以了。如何使用这些参数:在方法中此参数是被当作数组类访问的,调用length就可以知道有多少参数传进来,这种参数既能接受单个元素做
51、参数,也可以接受数组作参数。也就是说可变长的参数类型兼容了数组参数类型,但是数组参数类型不能兼容可变长参数类型。使用可变长参数的规定:a、 一个方法只能有一个可变长参数,而且该参数必须是这个方法的最后一个参数;b、 可变长参数的方法只有在必须的时候才被调用,也就是说,如果有不可变长参数的方法可以匹配,这种调用,那么系统会优先选择不可变长参数的方法的调用。19. 包装类Java使用简单的类型,例如整型(int)和字符(char)。这些数据类型不是对象层次结构的组成部分。它们通过值传递给方法而不能直接通过引用传递。而且,也没有办法使两种方法对整型(int)引用同一实例(sameinstance)。
52、有时需要对这些简单的类型建立对象表达式。为了满足这种需要,Java提供了与每一个简单类型相应的类。本质上,这些类在类中包装(wrap)简单类型。因此,它们通常被称作类型包装器(wrappers)。19.1. Number抽象类Number是BigDecimal、BigInteger、Byte、Double、Float、Integer、Long和Short类的超类。Number的子类必须提供将表示的数值转换为byte、double、float、int、long和short的方法。抽象类Number定义了一个由包装数字类型字节型(byte),短整型(short),整型(int),长整型(long)
53、,浮点型(float)和双精度型(double)的类实现的超类。Number有返回上面不同数字格式的对象值的抽象方法。也就是,doubleValue()方法返回双精度(double)值,floatValue()方法返回浮点(float)值等。19.2. 自动封箱/自动解封(Autoboxing/Unboxing)在JDK1.5之前要获得一个基本类型的对象比如Integer只能用Integer i=new Integer(5)或者Integer i=Integer.valueOf(5)但在JDK1.5以后可以直接写成Integer i=5;在这里虚拟机默认的为这个基本数据类型进行了包装,以上面的
54、第二种形式即:Integer i = Integer.valueOf(5);这种自动的包装叫做自动封箱。另外还可以自动解封,比如:int a=i;这种形式就相当与int a = Value();19.3. 对象池除了字符串类型的对象会创建对象池,八种基本类型的包装类也会创建对象池。但是这些包装类new出来也只创建一个对象,Integer的对象池在启动的时候就创建好了,范围是-128127之间,所以在这之间的数字对象都不会再创建新对象,超出的部分都会再创建新对象,不会在从对象池中拿。例如:Integer i1=5;/对象池中拿Integer i2=5;/i1= =i2Integer i
55、3=new Integer(5);/重新创建一个对象,所以i2!=i3同理String的另一个特点,Integer对象的值也是不可改变的。所以频繁的创建修改Integer对象也会生成很多垃圾。但是Integer的根本是int基本类型,所以直接用int就可以了。像:for(int i=0;i<1000000;i+)而不用复杂的把i定义成Integer。public class IntegerTest public static void main(String args) Integer i1 = 5;Integer i2 = Integer.valueOf(5);/ 上面两种形式都是从对象池中拿对象,所以它们相等Integer i3 = new Integer(5);Syst
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年低空智联平台跨部门数据互通与共享机制设计
- 2026年适老化产品品类不足精细度有待提升公共样板间弥补短板
- 江苏省苏州市相城区重点达标名校2025-2026学年初三4月中考测试化学试题理试题含解析
- 湖北省巴东县2026届初三毕业班第一次质检化学试题含解析
- 天津市河西区第四中学2025-2026学年下学期普通高中期末考试试卷初三化学试题含解析
- 山东省临沂达标名校2026届初三6月中考考前仿真化学试题含解析
- 2026年湖南省耒阳市冠湘中学初三练习题一(全国卷II)生物试题含解析
- 上海市杨浦区名校2026届初三第五次模拟考化学试题试卷含解析
- 2026届湖北省鄂州梁子湖区四校联考初三生物试题第一次月考含解析
- 四川省乐山市沙湾区2025-2026学年初三第一次适应性测试自选模块试题含解析
- 2026年食品安全与环境管理的关系
- 2025-2026学年湘美版美术八年级下册1.3走向现代课件
- 高中英语必背3500单词表完整版
- 硬笔行楷经典字帖
- 文创艺术片区现状调研报告
- GB/T 10002.1-2006给水用硬聚氯乙烯(PVC-U)管材
- 第八章-作为审美范畴的优美与崇高-(《美学原理》课件)
- 土木工程专业认识教育课件
- 动脉血气分析六步法杜斌
- 说明书hid500系列变频调速器使用说明书s1.1(1)
- 全套电子课件:数据结构(C语言版)(第三版)
评论
0/150
提交评论