Java基础知识总结
1.封装的两个含义:把该隐藏的隐藏起来,该暴漏的暴漏出来。
2.对于顶级类而言进行访问控制级别只能有public和默认,而不可以使用private和default。
3.类里面的绝大部分属性都应该用private修饰,除了一些static修饰的,工具方法也应该用private修饰。
4.某个类作为其他类的父类,应该用protected修饰。
5.在有包的情况下采用javac -d. Example.java来进行编译。通常无论有无包,都用这种编译方法。
6.包机制用来解决命名冲突和类文件管理等问题。
7.包名都用小写字母,类名的第一个字母大写。并且源文件和编译后的class文件应该分开存放。
8.合适的包名:要使用公司Internet域名到写来作为包名,如域名是wangjie.com包名为com.wangjie,则该公司的所有类都建议放在com.wangjie包及其子包下。
9.同一个包下的类可以自由访问,无需添加包前缀。
10.import pk.*只可以导入pk包下的所有类,但无法导入其子包下的类。
11.构造器的最大用途是在创建对象时执行初始化,通常用public来修饰。
12.通常建议为Java类保留无参数的默认构造器,因此,如果为一个类编写了有参数的构造器,通常建议为该类额外编写一个无参数的构造器。
13.构造器也可以重载,名字相同参数不同。与方法重载类似。
14.使用this调用另一个重载的构造器只能在构造器种使用,而且必须作为构造器执行体的第一条语句。
15.java的子类不能获得父类的构造器,Java类只能有一个直接父类,但其可以有多个间接父类。
16.子类包含父类同名方法的现象称为方法的重写。方法名相同参数相同子类方法返回值类型应比父类方法返回值类型更小或相等。
17.如果需要在子类方法中调用父类被覆盖的实例方法,可以使用super作为调用者来调用被覆盖的实例方法。
18.this和super都不可以出现在static修饰的方法中。
19.BaseClass a=new SubClass();这个a引用变量的编译时类型是BaseClass,而运行时类型是SubClass,相同类型的变量执行同一方法是呈现出的行为特征就是多态。注意:这里的a只能调用BaseClass类的方法二不能调用SubClass类里的方法。
20.引用类型之间的强制类型转换只能把一个父类变量转换成子类类型,如果是两个没有任何继承关系的类型,则无法进行类型转换。
21.instanceof的作用是:在执行强制类型转换之前,首先判断前一个对象是否是后一个类的实例,是否可以成功转换,从而保证代码更加强壮。
22.继承的最大缺点是:破坏封装。而组合是实现类重用的重要方式,采用组合方式类重用则能提供更好的封装性。
23.为了保证父类良好的封装性,不会被子类随意改变,设计父类通常应该遵循以下规则:
(1)尽量隐藏父类的内部数据,尽量把父类的所有属性都设置成private访问类型,不用让子类直接访问父类的属性。
(2)不要让子类可以随意访问、修改父类的方法。父类中那些仅为辅助其他的工具方法,应该使用private访问控制操作符,让子类无法访问,如果父类中的方法需要被外部类调用,必须以public修饰,但又不希望子类重写该方法,可以使用final修饰符来修饰方法,如果希望父类的某个方法被子类重写,但又不希望被其他类自由访问,可以使用protected来修饰。
(3)不用在父类构造器中调用被子类重写的方法。
24.如果只出于类复用的目的,并不一定需要使用继承,完全可以使用组合来实现。继承要表达的是一种“是(is-a)”的关系;而组合表达的是“有(has-a)”的关系。
25.当java创建一个对象时,系统先为该对象的所有实例属性分配内存,接着程序开始对这些实例属性执行初始化,其初始化的顺序是:先执行初始化快或生命属性时指定的初始值,再执行构造器里指定的初始值。
26.java提供了final关键字来修饰变量,方法和类,系统不允许为final变量重新赋值,子类不允许覆盖父类的final方法,final类不能派生子类。通过使用final关键字,允许java实现不可变类,不可变类会让系统更加安全。
27.为了解决8个基本数据类型的变量不能当成Object类型变量使用的问题,java提供了包装类的概念,为8个基本数据类型分别定义了相应的引用类型,并称之为基本数据类型的包装类。
28.自动装箱就是可以把一个基本类型变量直接赋给对应的包装类变量,或者赋给Object变量。自动拆箱允许直接把包装类对象直接赋给一个对应的基本类型变量。
29.除Character之外的所有包装类都提供了一个parseXxx(String s)静态方法,用于将一个特定字符串转换成基本类型变量;String类里也提供了多个重载valueOf()方法,用于将基本变量转换成字符串。如:把一个字符串转换成int变量int it=Integer.parseInt(intStr);把一个float变量转换成String变量String fstr=String.valueOf(2.12f);
30.如果希望把基本类型变量转换成字符串一个更简单的方法是将基本类型变量和“”进行连接运算,系统会自动把基本类型变量转换成字符串,如:String intStr=5+“”;
31.System.out.println(p);与System.out.println(p.toString());效果完全一样。
String pStr=p+””;与String pStr=p.toString()+””;完全一样。
32.toString方法是一个非常特殊的方法,它是一个“自我描述的方法,该方法通常用于实现这样一个功能:当程序员直接打印该对象时,系统将会输出该对象的“自我描述”信息,用以告诉外界该对象具有的状态信息。该方法总是返回“该对象实现类名+@+hashCode”值,但这并不是真的自我描述,若要实现自我描述就要重写toString()方法,通常格式为:
类名【属性 1=值1,属性2=值2,........】
例如:public String toString(){return “Apple【color=”+color+“,weight=”+weight+”】”;}
33.equals()方法判断两个字符串相等的标准是:只要两个字符串所包含的字符串序列相等,通过equals()比较将返回true,否则返回false。
34.如果一个类始终只能创建一个实例,则这个类被称为单例类。
35.final修饰成员变量必须初始化否则将没有任何意义。Final修饰成员变量值允许一次赋值,不可二次赋值。
36.java可读性命名规则:常量名由多个有意义的单词连缀而成,每个单词的所有字母全部大写,单词与单词之间以下划线分别,如:MY_BOOKS_NAME。
37.final修饰的方法不可以被重写,如果不希望子类重写父类的某个方法,用final修饰。
38.如果某个对象需要重复频繁使用,缓存该实例很有利。
39.抽象方法和抽象类的规则:
*抽象类和抽象方法必须使用abstract修饰符来修饰,抽象方法不能有方法体。
*抽象类不能被实例化,无法使用new关键字来调用抽象类的构造子创建抽象类的实例,即使抽象类里不包含抽象方法,这个抽象类也不能创建实例。
*抽象类可以包含属性、方法、构造器、初始化快、内部类、枚举类六种成分,抽象类的构造器不能用于创建实例,主要是用于被子类调用。
*含义抽象方法的类(包括直接定义了一个抽象方法;继承了一个抽象父类,但没有完全实现父类包含的抽象方法;以及实现了一个接口,但没有完全实现接口包含的抽象方法三种情况)只能被定义成抽象类。
40.由以上规则不难发现抽象类同样能包含和普通类相同的成员,只是抽象类不能用于创建实例,普通类不能包含抽象方法,而抽象类可以包含抽象方法。
41.利用抽象类和抽象方法的优势,我们可以更好的发挥多态的优势,是程序更加灵活。
42.final与abstract,static与abstract永远无法一起使用。
43.抽象类体现的就是一种模板的设计模式——最常见最简单的设计模式之一。其原理是:
抽象类可以只定义需要使用的方法,其余的方法则留给子类去实现,父类中可能包含需要调用的其他系统方法的方法,这些被调用方法及可以有父类实现,也可以有其子类实现,父类里提供的方法只是定义了一个通用算法,其实现也许不完全由自身实现,而必须依赖于其子类的辅助。
44.接口不能包含普通方法,接口里的所有方法均为抽象方法。接口里的所有成员都必须是pubic访问权限,接口为多继承,类为单继承,一个类可以实现多个接口,并且implements必须在abstract之后。
45.面向接口编写,这里有一个简单工厂模式和一个命令模式。
46.内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类。内部类成员可以直接访问外部类的私有数据,因为内部类被当成其外部类成员,同一个类成员之间可以互相访问,但外部类不能访问内部类的实现细节,例如内部类的属性。
匿名内部类适用于创建那些仅需要一次使用的类。内部类编译后的文件名总是这种形式:OuterClass$InnerClass。
47.非静态内部类的成员可以访问外部类的private成员,反过来不成立了。如果外部类需要访问非静态内部类成员,则必须显式创建非静态内部类对象调用访问其实例成员。
49.注意根据静态成员不能访问非静态成员的规则,外部类的静态方法、静态代码不能访问非静态内部类。不允许在外部类的静态成员中直接使用非静态内部类。静态内部类里不可以有静态初始化块。
50.对于局部成员而言,不管是局部变量还是局部内部类,他们的上一级成像单元是方法二不是类使用static修饰他们没有任何意义,因此所有局部成员都是不能使用static修饰的。
51.匿名内部类适合创建那种只需要一次使用的类,它不能被重复使用。
52.匿名内部类规则:
*匿名内部类不能是抽象类,因为系统在创建匿名内部类的时候,会立即创建匿名内部类的对象。因此不允许将匿名内部类写成抽象类。
*匿名内部类不能定义构造器,因为匿名内部类没有类名,所以无法定义构造器,但匿名内部类可以定义实例初始化块,通过初始化块来完成构造器要实现的功能。
53.最常见的创建匿名内部类的方式是需要创建某个接口类型的对象。
54.由于匿名内部类不能是抽象类,所以匿名内部类必须实现它的抽象父类或接口里包含的所有抽象方法,记住必须是所有抽象方法。
55.如果匿名内部类要访问外部类的局部变量,则必须使用final修饰符来修饰外部类的局部变量,否则将会报错。
56.枚举类与普通类的区别:
*枚举类可以实现一个或多个接口,使用enum定义的枚举类默认继承了Java.lang.Enum类,而不是继承Object类。
*枚举类的构造器只能使用private访问控制符,如果省略了其构造器的访问控制符,则默认使用private修饰;如果强制指定访问控制符,则只能指定private修饰。
*枚举类的所有实例必须在枚举类中显式列出,否则这个枚举类将永远都不能产生实例。列出这些实例时,系统会自动添加public static final修饰,无需程序员添加。
*所有枚举类都提供了一个values方法,该方法可以很方便地遍历所有的枚举值。
57.枚举类通常设计成不可变类,我们应将枚举类的属性都使用private final修饰。
58.强制系统垃圾回收的两种方法:
*调用System类的gc()静态方法System.gc(),运行命令是:Java-verbose:gc()。
*调用Runtime对象的gc()实例方法Runtime.getRuntime.gc()。
59.一旦Java程序中包含看native方法,这个程序将失去跨平台的功能。
60.使用JAR文件的好处:
*安全。能够对JAR文件进行数字签名,只能够识别数字签名的用户使用里面的东西。
*加快下载速度。在网上使用Applet时,如果存在多个文件而不打包,为了能够把每个文件都下载到客户端,需要为每个文件单独建一个HTTP连接,这是非常耗时的工作。使用文件压缩成一个JAR包,则只要建立一次HTTP连接就能够一次下载所有文件。
*压缩。使文件变小,JAR包压缩机制和ZIP完全相同。
*包封装。能够让JAR包里面的文件依赖于统一颁布的类文件。
*可移植性。能够让JAR包作为内嵌在Java平台内部处理的标准,能够在各个平台上直接使用。
61.创建可执行JAR包,大概有一下三种发布方式:
*使用平台相关的编译器将整个应用编译成平台相关的可执行性文件,这种方式需要第三方编译器的支持,而且编译生成的可执行性文件丧失了跨平台特性,甚至可能有一定的性能下降。
*为整个应用编译一个批处理文件。在Windows操作系统,批处理文件只需要定义如下命令:java package.MainClass,当客户单击上面的批处理文件时,系统将执行批处理文件的java命令,从而运行程序的主类。如果不想保留Java程序的命令窗口,也可以在批处理文件中定义如下命令:start javaw package.MianClass。
*将一个应用程序制作成可执行的JAR包,通过JAR包来发布应用程序。
62.遍历Collection集合使用Iterator接口,Iterator必须依附于Collection对象,有一个Iterator对象则必然有一个与之关联的Collection对象,没有Collection那么Iterator无任何意义。使用Iterator来迭代访问Collection集合元素,Collection里的元素不能被改变,只有通过Iterator的remove方法开删除上一次next方法返回的集合元素才可以,否则将引发异常。
63.使用foreach循环遍历集合元素更加便捷,并且该集合也不能被改变。
64.Set集合不能允许有相同的元素,Collection集合允许有相同的元素,Set集合的HashSet类常用,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等且两个对象hashCode返回值相等。
65.Java的泛型可以保证如果程序在编译时候没有警告,运行时就不会产生ClassCastException异常。
66.Java的参数化类型被称为泛型,泛型就是允许在定义类接口时指定类型参数,这个类型形参将在声明变量创建对象时确定。
67.在静态方法静态初始化成静态变量的声明和初始化中不允许使用类型形参,instancef运算符不能使用泛型。
68.如果Foo是Bar的一个子类型,而G是具有泛型声明的类或接口,那么G<Foo>是G<Bar>的子类并不成立,这一点要非常注意,因为它与我们的习惯看法不同。
69.泛型通配符(?)
70.JDK1.5的泛型有一个很重要的设计原则:如果一段代码在编译时没有产生“【unChecked】未经检查的转换”警告,则程序在允许时不会引发“ClassCastException”异常。
71.Scanner获取键盘输入注意提供两个方法:hasNextXxx()表示是否有下一项,nextXxx()表示获取下一个输入项,提供两个简单的方法来逐行读取boolean hasNextLine(),
String nextLine()。如:Scanner sc=new Scanner(System.in);其中System.in代表键盘输入。
Scanner读取一个文件 Scanner sc=new Scanner(new File(“a.txt”));
72.Runtime提供访问JVM相关信息的方法,还可以直接单独启动一条过程来运行OS的命令。
73.String Builder类代表字符串对象,在通常情况下,如果需要创建一个内容可变的字符串对象,应优先考虑使用StringBuilder。Sting类是不可变类,一旦对象创建则不可改变。
74.相对于Math的random而言,Random类提供了更多的方法来生成各种伪随机数,它不仅可以生成浮点数类型的伪随机数,也可以生成整数类型的随机数,还可以指定生成随机数的范围。而Math的random返回一个伪随机数,该值大于0.0且小于1.0的浮点数。
75.为避免两个Random对象产生相同的随机数序列,通常推荐使用当前时间来作为Random对象的种子。代码如下:Random rand=new Random(System.currentTimeMills());
76.Java提供Calendar类来更好的处理日期、时间而Date类在设计上存在缺陷,因此Date类不推荐使用,推荐使用Calendar类。Calendar类是抽象类,因此不能直接实例化,只能创建calendar的子类实例。
77.IBM开发人员实现了多种日历,网址:http:www.alphaworks.ibm.com/tech/calendars。
78.月份起始值是0,int.get(int field)来取出年月份时间如:c.get(MONTH);,c.get(DATE);
79.中国北京时间属于东八区,timeZone类表示时区。
80.几种常见的异常:
*如果运行程序时输入的参数不够,将发生数组越界异常,Java运行时使用IndexOutOfBoundsException对 应的catch块处理异常。
*如果运行程序输入的不是数字而是字母,将发生数字格式异常,Java运行时将调用NumberFormatException对应的catch块处理该异常。
*如果运行程序输入的第二个参数是0,将发生除0异常,Java运行时将调用ArithmeticException对应的catch块处理该异常。
81.进行异常捕获一定要记住先捕获小的异常再捕获大的异常,应该把catch{Exception e}放在所有的catch块的后面,即放在最后。
82.为保证一定能回收try块中打开的物理资源,异常处理机制提供了finally块,并且finally块总是被执行。
83.子类方法中不允许比父类方法声明抛出更多的异常。
84.自定义异常类:(通常只需将AuctionException修改为一个可以直接描述该异常的名字即可)
public class AuctionExeption extends Exception{
//异常类无参数的构造器
public AuctionException(){}
//带一个字符串参数的构造器
public AuctionException(String msg){
super(msg);
}
}
85.catch与throw结合使用的情况在大型企业级应用中非常常用,企业级应用对异常的处理通常需要分成两个部分:一、应用后台需要通过日志来记录异常发生的详细情况。二、应用还需要根据异常向应用使用者传达某种提示,在这种情况下所有异常都需要这两个方法共同完成,即必须将catch与throw结合使用。
86.设计模式之一:职责链模式也被称为“异常链”。
87.所有包含多个方法的监听器接口都有对应的事件适配器,但只包含一个方法的监听器接口则没有对应的适配器。
浙公网安备 33010602011771号