Java开发中容易被忽视的东西

来源:互联网 发布:经典算法详解 编辑:程序博客网 时间:2024/05/15 03:49

 

很多时候,习惯了开发的模式,往往会忽视一些基础的东西,而这些基础东西往往是开发有一定技术含量的模块所不能忽视的。

在此记下Java开发中容易被忽视的东西。

 

1)== 与 equals() 区别
      == 既能用于基本数据类型比较又能用于引用类型比较,对于基本数据类型直接比较值是否相等,对于引用类型比较的是引用地址。
      equals()用于引用类型比较,默认是当两个对象是同一个对象的引用时返回true,否则返回false,可根据需要在用户自定义类型中重写equals()方法,JDK提供的一些类如:String和Date等,已经重写了Object的equals() 方法,当两个对象是同一类对象且属性内容相等时(并不一定是相同的对象),返回true,否则返回false。

2)byte,short,char间不能相互转换,若要转换需要借助于int类型。

3)Java中的基本数据类型可分为四类八种,分别是整形(byte,short,int,lang)字符型(char)浮点型(float,double)布尔型(boolean),整型默认是int,浮点型默认是double,对于大于int型最大值的整数需要在后面加上l或者L,对于float型浮点数要在后面加上f或者F,对于常用的String类型是Java对象,不属于基本数据类型。

4)final 关键字
     a) final标记的类不能被继承。
     b) final标记的方法不能被子类重写。
     c) final标记的变量(成员变量或局部变量)即成为常量,只能赋值一次。
     d) 方法中定义的内置类只能访问该方法内的final类型的局部变量。

5)Java中类放在内存代码区,局部变量(包括引用)放在内存栈中,new出来的对象放在内存堆中。

6)构造方法与类名完全一致,没有返回值,也不能写void,new的时候调用的是构造方法,在对象产生之前,构造参数放在栈中,在对象产生时传递到堆中,随后自动释放。

7)在没有构造方法时,系统会有一个默认的空的构造方法,若定义了其它的构造方法,系统则不再提供默认构造方法。

8)类名首字母大写,方法名和变量名首字母小写,运用驼峰标识。

9)一个.java文件名要与public类的类名一致且只能有一个public类(除内部类)。

10)值传递只改变形参不改变实参,引用传递可通过set方法来改变传入引用所指对象的值(不能用new),引用形参在方法调用后消失。

11)基础类型占一块儿内存,引用类型占两块儿内存。

12)形参也在栈内存中占用空间,方法调用完成后自动消失。

13)返回值在内存中也占有空间,方法调用返回后自动消失。

14)main方法结束后,与其相关的内存空间都将被回收。

15)方法重载(Overload)是指一个类中可以定义有相同的名字,但参数不同的多种方法,参数个数或类型要不同,同名且参数一致而返回值不同的属于重名,允许有不同的返回值,但是需要参数个数或者类型不一致,除了普通方法,构造方法也可以重装,总之要确保编译器能够区别你所调用的重载方法。

16)main可以在.java文件的多个 类中声明,但是只有public类中的main才是真正的出口,对于其它非public类中的mian只能算是一个静态的main方法。

17)必须使用new关键字创建对象,同一类的每个对象有不同的成员变量存储空间,同一类的每个对象共享该类的方法,方法只有在被调用的时候才调入内存并分配相应的空间,非静态方法是针对每个对象进行调用的。

18)System.out.print是输出不换行,System.out.println是输出换行,System.out.printf是格式化输出。

19)在类的方法定义中使用的this关键字代表使用该方法的对象的引用,有时使用this可以处理方法中成员变量和参数重名的情况,this指向当前对象,super指向当前对象的父对象。

20)在类中,用static声明的成员变量为静态成员变量,它为该类的公用变量,在第一次使用时被初始化,存储在数据区(data segment),对于该类的所有对象来说,static成员变量只有一份,主要是通过类名(非实例化)直接访问,也可通过对象的引用访问。

21)在类中,用static声明的方法为静态方法,在调用该方法时,不会将对象的引用传递给它,所以static方法中不可以访问非static的成员。

22)Java内存布局主要可分为四部分,即代码区(code segment),存放程序代码;栈区(stack),存放引用和局部变量及方法的参数和临时返回值;堆区(heap),存放new出来的对象;数据区(data segment),用于存放静态成员变量及字符串常量。

23)静态方法不能访问非静态成员。

24)package语句作为Java源文件的第一条语句,指明该文件中定义的类所在的包(若缺省该语句,则指定为无名包),必须保证该类的class文件位于正确目录下,该类的源码可能会产生影响,需要删除或转移到另外的目录;另外的类需要访问的话,需要写全名,或者引入*,或者引入带包的具体类名,访问位于同一个包中的类不需要引入;class 文件的最上层包的父目录必须位于calsspath下。

25)除了java.lang外,其它的包要用的话必须引入。

26)若在.java中设置了package,则编译出来的.class文件就必须位于设置的package目录下,否则是无法访问的。

27)class权限只能用public或default来修饰(除了内部类),public类可以在任意地方被访问,default 类只可以被同一个包内部的类访问。

28)一个子类只能有一个父类,一个父类可以派生出多个子类,通过继承,子类自动拥有父类所有的成员(成员变量和方法),但并不是都能够访问,无修饰符(default):不能访问,子类跟父类在同一个包下除外;private:不能访问,子类为父类的内部类时除外;public和protected:能访问。

29)子类可根据需要对父类中继承的方法进行重写(Overwrite或Override),重写方法和被重写方法具有相同的方法名称,参数列表和返回类型,重写方法不能使用比被重写方法更严格的访问权限。

30)构造一个子类对象前必须先构造父类对象,在子类的构造过程中必须调用其父类的构造方法;子类可以在自己的构造方法中使用super(argument_list)调用其父类的构造方法(必须写在子类构造方法的第一行),使用this(argument_list)调用本类的另外的构造方法;若子类的构造方法中没有显示地调用父类的构造方法,则系统默认调用父类无参的构造方法;若子类构造方法中既没有显式调用父类构造方法,而父类中又没有无参的构造方法,则编译出错。

31)若对构造方法进行重载则系统将不再默认提供无参的构造方法,必须声明显示的无参数构造方法,否则编译出错。

32)Object类是所有Java类的根父类,如果在类的声明中未使用extends关键字指明其父类,则默认父类为Object类。

33)在进行String与其它类型数据的连接操作时,将自动调用该对象类的toString()方法,用户可以根据需要在自定义类型中重写toString()方法。

34)对象转型(casting),一个基类的引用类型变量可以指向其子类的对象;一个基类的引用不可以访问其子类对象新增加的成员(属性和方法);可以使用引用变量instanceof类名来判断该引用型变量所指向的对象是否属于该类或该类的子类;子类的对象可以当作基类的对象来使用称为向上转型(upcasting),反之称为向下转型(downcasting)。

35)动态绑定是指在执行期间(而非编译期间)判断所引用对象的实际类型,根据其实际的类型调用其相应的方法(方法存在代码区code segment),多态的实现需要三个条件a:要有继承,b:要有重写,c:父类引用指向子类对象。

36)用abstract关键字来修饰一个类时,这个类叫做抽象类;用abstract来修饰一个方法时,该方法叫做抽象方法。含有抽象方法的类必须被声明为抽象类,抽象类必须被继承,抽象方法必须被重写。抽象类不能被实例化。抽象方法只需声明,而不需要实现,相当于C++中的纯虚函数。抽象类虽然不能被实例化,但是可以作为父类引用指向子类对象。

37)接口(interface)是抽象方法和常量值的定义的集合。从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。接口中的方法不用写abstract就已经默认是abstract的了。接口可以多重实现,接口中声明的属性默认为public static final的,也只能是public static final的;接口中只能定义抽象方法,而且这些方法默认为public的,也只能是public的。接口可以继承其它的接口,并添加新的属性和抽象方法。多个无关的类可以实现同一个接口。一个类可以实现多个无关的接口。与继承关系类似,接口与实现类之间存在多态性。

38)方法后的throws用于指明可能会抛出的异常,具体怎样抛出异常,使用throw,然后用try...catch来捕获并处理异常。

39)JDK中定义了各种异常类,而Throwable类是错误及异常类的根类。Error是虚拟机生成并抛出的错误,包括动态链接失败、虚拟机错误等,程序对其不做处理,也是开发人员无法处理的;Exception是所有异常类的父类,其子类对应了各种各样可能出现的异常事件,一般需要开发人员显式的声明或捕获,是开发人员可以处理的。

40)Runtime Exception 一类特殊的异常,如被0除、数组下标超范围等,其产生比较频繁,处理麻烦,如果显式的声明或捕获将会对程序可读性和运行效率影响很大,因此由系统自动检测并将它们交给缺省的异常处理程序,用户可不必对其处理。

41)对于java.io.IOException是必须捕捉或声明的,否则可能无法通过编译。

 42)try代码段包含可能产生异常的代码,其后可跟一个或多个catch代码段,每个catch代码段声明其能处理的一种特定类型的异常并提供处理的方法。当异常发生时,程序会中止当前的流程,根据获取异常的类型去执行相应的catch代码段。finally段的代码无论是否发生异常都会执行,通常进行资源的清除工作。

43)异常的捕捉应当先小后大,比如同时捕捉IOException和FileNotFoundException,若先捕捉前者则会编译出错。

44)使用自定义异常的一般步骤如下,a)通过继承java.lang.Exception(或者java.lang.RuntimeException)类声明自己的异常类。b)在方法适当的位置生成自定义异常的实例,并用throw语句抛出。c)在方法的声明部分用throws语句声明该方法可能抛出的异常。

45)重写方法需要抛出与原方法所抛出异常类型一致的异常或不抛出异常。

46)Java中声明数组时不能指定其长度(数组中元素的个数),例如 int arr[10] ; 是非法的。Java中使用关键字new创建数组对象。元素为引用数据类型的数组中的每一个元素都需要实例化。数组的静态初始化不能指定数组长度,而应由Java根据初始化的内容自动指定。

47)数组(包括String[])有length属性而没有length()属性,String有length()方法而没有length属性。

48)Java中多维数组的声明和初始化应按照从高维到低维的顺序进行,多维数组可以看成是数组的数组,如:可以int[ ][ ] a = new int[10][ ],不可以int[ ][ ] a = new int[ ][10]。

49)数组在内存中往往是连续存储的,数组间的拷贝可以用System.arraycopy(src, srcPos, dest, destPos, length)方法。

 50)Java中的常用类包括字符串相关类(java.lang.String、java.lang.StringBuffer),基本数据类型包装类,Math类,File类,枚举类。String类代表不可变的字符序列,而StringBuffer代表可变的字符序列。字符串常量分配在数据区(Data Segment)区,对于String s1 ="abc" 与 String s2 = "abc",s1与s2是指向数据区的同一区,s1等于s2,若String s1 = new String("abc") 与 String s2 = new String("abc")来说,s1,s2 指向堆中不同区,s1不等于s2。

 51)静态重载方法public static String valueOf(...)可将基本数据类型转换为字符串;方法public String[] split(String regex)可将一个字符串按照指定的分隔符分隔,返回分隔后的字符串数组;对于String.valueOf(Object obj),返回的是obj的toString()方法的返回值,这里用到了父类引用指向子类对象,也是多态的应用。

52)向右倾斜的斜杠"/"是正斜杠,向左倾斜的斜杠"\"是反斜杠。Linux的文件路径分隔只可用"/",而Windows的文件路径分隔符默认为"\",也可用"/",由于反斜杠"\"常用来表示转义字符,所以文件路径中要用"\\"来分隔,若考虑程序跨平台可以通用"/"为文件路径分隔符或者用File的静态属性separator。

 53)java.lang.Enum枚举类型,只能够取特定值中的一个,使用enum关键字定义。

 54)Set与List继承自Collection接口,Set不允许元素重复且没有顺序,List允许元素重复并且有顺序,HashSet继承自Set,ArrayList和LinkedList继承自List,HashMap 与TreeMap继承自Map,存储的是键值对,键值不能重复。所有实现了Collection接口的容器类都有一个iterator方法用以返回一个实现了Iterator接口的对象。

 55)类java.util.Collections提供了一些静态方法实现了基于List容器的一些常用算法,所有可以“排序”的类都实现了java.lang.Comparable接口,Comparable接口中只有一个CompareTo()方法。

 56)Array读快改慢,Linked改快读慢,Hash介于两者之间。

 57)Auto-boxing/unboxing 及自动打包(自动将基础类型转换为对象),解包(自动将对象转换为基础类型)。

 58)JDK1.5增加泛型是因为JDK1.4以前类型不明确,装入集合的类型都被当作Object对待,从而失去自己的实际类型,从集合中取出来时往往需要转型,效率低,容易产生错误,而泛型可以在定义集合的时候同时定义集合中对象的类型,例如可以在定义Collection的时候指定,也可以在循环时用Iterator指定,增强了程序的可读性和稳定性。只有在类后跟有<>的类才可以用泛型,在JDK帮助文档中可查。

59) java.io包中定义了多个流类型(类或抽象类)来实现输入/输出功能;从不同的角度:1)按照数据流的方向不同可分为输入流与输出流,2)按照处理数据单位的不同可分为字节流和字符流,3)按照功能不同可分为节点流和处理流。所有流类都继承自InputStream,OutputStream,Reader,Writer 这四个抽象类,其中前两个属于字节流,后两个属于字符流。所谓的输入与输出是站在程序的角度来说的,从数据源到程序为输入,从程序到数据源为输出。

60)节点流为可以从一个特定的数据源(节点)读写数据(如:文件,内存),可以理解为数据源与程序由一条管道连接;处理流是“连接”在已经存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更加强大的读写功能,可以理解为数据源与程序由管道套管道的方式连接。

 

 

 

 

 

 

 

原创粉丝点击