1、Java详细总结精辟版+Java总结-开始于2013-9-7 09:27:48Java概述Java分类:java SE:主要是桌面程序、控制台程序开发,是java基础java EE:企业级开发(网站开发和基于b/s模式的编程)java ME:嵌入式开发(手机软件、小家电)第一个Java程序:public class JavaTest private String str = new String(hello java.); public void showMessage() System.out.println(str); public static void main(String args
2、) JavaTest test = new JavaTest(); test.showMessage(); Java可以有多个main函数。每个类中都可以有main函数,也就是说你的代码可以有多个入口,你只需要明白什么时候用哪个类的main函数作为入口即可。但是要注意的是用不同入口启动的两个进程是毫不相关的。学习Java前的心理准备: java他妈的把c/c+剔除的够干净的,在c/c+中易如反掌的事,在java中却要大动干戈。所以在学习java之前,请做好心理准备,java其实是一个残疾人。Java关键字、运算符Java保留字一览表:java中goto是保留字,但不是关键字,请记住java中没
3、有goto,但可以实现类似的功能,参考XX。java中没有sizeof,因为java认为c语言中的sizeof主要用于跨平台,而java本身就是跨平台的。java中没有unsigned,也就是说java中的基本数据类型都是有符号的。这点要注意一下。请注意下面的代码:int a = ;int b = ;int c = a b;以上代码只有在a和b都是无符号的int时才能正确工作。对于java这种没有unsigned类型的语言来说,上述代码就是一个编程错误!因为int不足以容纳两个有符号int的差,当a是很大的正整数,b是很大的负整数时,a-b就会溢出并返回负值。Java运算符: java运算符和
4、c、c+的运算符类似,功能也类似。但也有不同,比如java中有无符号右移运算(逻辑右移):。同时注意:用于String的“+”和“+=”是java中仅有的两个重载过的运算符,java不允许程序猿重载任何的运算符。Java数据类型Java是强数据类型的语言,java基本数据类型: boolean:true or false char:16bits,Unicode编码字符 byte:8bits short:16bits int:32bits long:64bits float:32bits,float var = 32.5f,注意加上“f”,否则带小数点的值都会被java当作double处理。 d
5、ouble:64bits在Java中,主数据(primitive)类型都有对应的被包装过了的类,以第一个字母大写开头,例如:Boolean、Integer、Character、Byte、Short、Long、Float、Double。 主数据类型可以与其对应的对象相互转化,在运算时,Java 5.0以后会自动进行转换,所以很方便。在使用ArrayList时,你只能声明对象,例如:ArrayList(其实这是泛型),而不能使用ArrayList,但是在使用ArrayList时,可以直接使用int类型。Java字节序: java在任何系统上的字节序都是大端(Big-endian),因为java是跨
6、平台的嘛。网络传输的字节序也是大端。因此java程序和java程序之间进行数据传输,并不会出现什么问题。但是当java遇到字节序是小端(Little-endian)的数据时,就会出现问题。这时我们就需要转换数据的大小端。方法有很多,你可以自己写方法实现大小端的检测和转换,但是作为java程序猿来说,我们应该尽量使用已有的类库或者方法来解决问题,以提高生产率。下面介绍几种java类库中已有的解决办法:1 使用java.nio.ByteBuffer类中的order方法将字节序改为小端。如:buffer.order(ByteOrder.LITTLE_ENDIAN);2 使用Integer等基本数据类
7、型对应的类类型中的静态方法将int等数据类型的数据转换为小端字节序的数据。如:Integer.reverseBytes(num);另外,在网络传输时,还需要注意其他问题:java没有unsigned;java数据类型的长度和其他语言的可能不同。同时,IEEE 754标准只是规范了float、double的逻辑规范,其存储时还是会有字节序问题,因此在不同系统或者编程语言之间进行传输数据时,也要考虑字节序问题。byte、int的转换: 由于java中所有的基本数据类型都是有符号的,所以当你要把byte类型的数据当作无符号数据看待时,你就得使用特殊的方法将其存放在更大容量的数据类型里边,比如将byt
8、e转换之后存放在int中。下面说下byte和int的相互转化:byte转换为int有两种方法:1 不改变原值,也即转换前后都将其看作有符号数,可使用强制类型转换:int i = (int)b;2 保留最低字节的个个位不变,则需采用位操作:int i = b & 0xff;int转换为byte可以直接使用强制类型转换:byte b = (byte)i;,注意这个操作是直接截取int中最低一个字节,如果int数值大于127且小于256,则转换得到的byte为负值(因为是有符号的,但其二进制位和int的最低字节完全相同),如果int数值大于255,则转换得到的byte就会面目全非,因为截断了。字符串
9、String: String是不可变字符串对象,任何修改String的操作,实际上返回的都是一个全新的String对象。String中保存的是Unicode格式的16位字符组成的字符串,String永远是Unicode编码。“+”、“+=”可以用来连接字符串。由于String是不可变的,因此在连续的字符串连接时,会不断的生成中间的String对象,以得到最终的String对象。这样的话,效率是很低的,java编译器为了提高效率,会暗地里为我们做一些优化,它用StringBuilder来处理中间过程的字符串连接,并最终使用toString()方法(从Object继承来的,当你要打印该对象时,你就
10、要覆盖toString()方法)将最终结果转换为String对象。在程序中,比如在循环连接字符串时,为了效率,最好使用StringBuilder来处理中间结果。StringBuilder是可变的,类似的还有StringBuffer,不过StringBuffer是线程安全的,因此开销相对也会大点。byte、char、String的转化:String.getBytes(“GBK”)取得其“GBK”编码格式的字节数组,“GBK”指出将字符串转换为何种编码并保存到字节数组,取得的字节数组的内容就是该字符串在“GBK”编码下的字节数组。String.getChars()将String转为char。new
11、 String(byte bytes, “UTF-8”),将bytes字节数组以“UTF-8”编码格式转换为Unicode,“UTF-8”指出字节数组是以什么格式编码的,并不是最终要转换成的编码。new String(chars)将char类型的数组chars转换为String类型。数字的格式化 Java中数字的格式化与C语言的很相似。 将数字以带逗号的形式格式化:String.format(“%,d”, 1000000); 注意:%和d之间有一个逗号。 Java中日期的格式化:String.format(“%tc”, new Date(); 其中,%tc表示完整日期,%tr只显示时间,%tA
12、 %tB %td 周 月 日 也可以这样写:String time = new SimpleDateFormat(yyyy-MM-dd).format(new Date(); 取得当前日期可以使用Date对象,Date中getTime()、setTime()都是针对GMT时间,toString()则会根据时区将时间转换为相应字符串,但其他关于日期的操作最好使用Calendar对象,具体参见Java手册。Java控制语句java中控制语句与c、c+类似,但与C/C+不同的是,java中的while、if等的条件判断,不能直接使用类似于int型的变量(看其是否等于0)来判断,应该用一个判断语句或者
13、直接使用boolean类型的变量。特殊循环语句:循环for(int cell : cells) 中,冒号(:)代表in,cells为数组,每循环一次cells数组的下一个元素都会赋值给cell变量。这是java 5.0(Tiger)开始使用的for循环加强版,当然你也可以使用for原版:for(int i=0; in; i+) foreach循环可以用于数组和任何实现了Iterable接口的类(这并不意味着数组肯定也是一个Iterable)。类和对象java中的所有东西都包含在类中,在java源文件中可以包括多个类,但是只能有一个public类,而且如果有public类的话,这个文件的名字要和
14、这个类的名字一样。一个类中可以有多个方法,一个方法中可以有多个语句。Java存取权限和存取修饰符: Java有4种存取权限和3种存取修饰符,因为有一个缺省的权限等级(无修饰符)。 4种存取权限:public:.private:.default:只有在同一个包中的默认事物能够存取protected:受保护的部分,运行起来像是default,但也允许不在同一个包中子类继承受保护的部分 3种存取修饰符:public、private、protected对象与引用:java中没有所谓的对象变量,有的只是对象的引用,对象只存在于堆上,并且只能通过其引用进行引用。java创建对象不能通过类似于“A a;”的
15、形式直接定义,这只是定义了一个对象引用变量,而需要通过类似于“A a = new A();”的形式在堆上定义一个对象,并将在栈上的对象的引用指向这个对象。c+中对象作为参数,是按照值传递。其实java也是值传递,只不过java中只有对象的引用,而没有所谓的“对象变量”,故而传递的都是对象的引用的值,因此在函数中可以改变引用参数指向的对象。注:java中String类型的对象作为函数参数传递时,也是传递引用的值,而不是所谓的“值传递”,因为String类是不可变的,它没有提供自身修改的函数,每次修改操作都是新生成一个String对象,所以要特殊对待,可以认为是传值。关于这一点,网上实在是有太多的
16、流言蜚语,有很多流言是错误的,请务必注意。那么有没有办法使函数不能够修改引用参数指向的对象呢?答案是传递对象副本的引用。为了使用对象的副本作为函数参数,可以使用对象的 clone() 方法对其进行浅层复制(具体细节请XX之),所谓的浅层复制即是只复制对象本身,而不对其引用的或者其成员变量引用的对象进行复制,也即不对整个对象网进行复制。对对象网进行复制(深层复制),另有它法,请XX之。对象相等性的判断:“=”或者“!=”只能用来判断对象的引用是否相等,若需判断对象是否相等,则需equals(),但一般你需要覆盖equals(),因为Object中的equals()默认使用对象的地址判断对象是否相
17、等。但基本类型直接使用“=”或者“!=”即可。实例变量与局部变量:实例变量是声明在类内,而不是方法中,实例变量有默认值。局部变量是声明在方法中的,局部变量没有默认值,在使用之前,必须初始化,否则编译器报错。关于初始化的更多细节:java中成员变量可以在定义的后边直接进行初始化,也可以在构造函数中进行初始化。而c+中成员变量不能在定义类时直接初始化,需通过构造函数初始化。final:声明一个类或方法到达继承树的末尾,可以用final,也即禁止该类被继承或方法被覆盖。同时请注意final方法是前期绑定的,将方法声明为final可以有效关闭该方法的动态绑定机制,但多数情况下并不会提升多少效率,因此不
18、要为了提升效率而随意使用final来声明方法。静态的方法:用static声明的方法是静态的方法,静态方法不需要实例化的对象,就可以通过类名来引用(当然也可以通过对象来引用),但静态的方法不可以使用非静态的变量,也不能调用非静态的方法。静态的变量:用static声明的变量是静态变量,静态变量为该类的所有对象共享,注意static不能作用于局部变量,只能作用于成员变量,因此只有成员变量才能是静态变量。 静态变量也会有默认值,就像实例变量一样会被自动初始化一样。静态变量会在该类任何的静态方法被调用之前被初始化,也会在该类任何的对象被创建之前被初始化。你可以像初始化其他成员变量一样,直接在定义处初始化
19、,也可以使用特殊的语法结构进行初始化静态块,如下: public class Spoon static int i; static i = 100;还有一种类似的初始化非静态成员变量的语法实例初始化块,只是没有static关键字而已。静态的final变量:静态的final变量是常数。其声明形式为:public static final var_name;静态的final变量必须被显式初始化,可以用以下两种方法之一初始化:1、声明时赋值:public static final double PI = 3.1415926; 2、在静态初始化程序中:public static final doubl
20、e PI; static PI = 3.1415926;Java终极对象:在java中的所有类都是从Object这个类继承出来的,也就是说Object是所有类的父类,它是非抽象的,允许被实例化。你可以显式声明类的继承对象为Object:public class Animal extends Object ,如果不显式声明的话,java编译器会隐含的进行继承。ArrayList就是通过声明Object对象为方法参数来处理所有的对象的,否则他不可能实现处理所有对象的功能。super与this:通过super可以调用父类中的方法,例如:super.isEmpty()。通过this可以调用本类中的方法
21、,例如:this.fun()。实际上,java会将this作为一个隐含的参数传递给类中的每一个方法。构造函数: 在构造器中调用具有多态行为的函数时,容易引起隐蔽的错误。为此,这里有一条有效的准则:“用尽可能简单的方法使对象进入正常状态,如果可以的话,避免调用其他方法,尤其是别调用具有多态行为的方法”。可以通过super()调用父类的构造函数,如果子类没有显式的调用父类的构造函数,则编译器会在子类的构造函数第一行加上super()调用,当然这里只能调用其父类的无参数的构造函数。当然你也可以自己写出具有参数的super()函数来调用父类的带参构造函数。可以通过this()从某个构造函数中调用同一个
22、类的另外一个构造函数。this()只能存在于构造函数中,且同super()一样,只能位于第一行语句。因此super()与this()不可兼得。垃圾回收器和对象清理:对于java中的垃圾回收器和对象的清理工作,请记住:垃圾回收器可能会被调用,也可能不会被调用,即使其被调用,它也可能以它想要的任何方式来回收垃圾。因此,对它不要抱过多幻想。当下,除了回收内存以外的其他任何事情(比如:已经打开的文件、网络连接、在屏幕上绘制的图形、甚至可以是外部世界的某个开关),你最好不要依赖于垃圾回收器,也不要依赖于finalize()(finalize()是被垃圾回收器调用的,使程序猿可以在垃圾回收器运行时做出一些
23、重要的动作,比如说回收一些非正常方式分配的内存),最好的办法就是程序猿自己编写好特定的方法调用即可,比如在finally中调用之。抽象类、抽象方法抽象类:声明形式为:abstract class Dog extends Animal 抽象方法:抽象方法允许你声明方法的名称、参数以及返回类型,但没有实体,直接以分号结束。例:public abstract void eat(); 抽象方法的意义是就算无法实现出方法的内容,但还是可以定义出一组子型共享的协议。注意:如果你声明一个抽象方法,那么也必须将该类标记为抽象的,你不能在非抽象类中拥有抽象的方法。第一个具体子类必须实现所有的抽象方法。内部类内部
24、类可以使用外部类所有的方法与变量,就算是私有的,也照样可以使用。当然,这是说内部类的实例可以存取它所属的外部类实例的所有方法与变量。一个内部类被嵌套多少层并不重要,它都能够透明地访问所有它所嵌入的外围类的所有成员。 在外部类中创建内部类的实例,就像普通的类的创建一样,例如:MyInner inner = new MyInner(); 在外部类以外的程序代码创建内部类的实例,要用特殊的语法:MyOuter outer = new MyOuter(); MyOuter.MyInner inner = outer.new MyInner(); 如果你需要生成对外部类对象的引用,可以使用外部类的名字后
25、边紧跟圆点和this的特殊语法,如:MyOuter.this 使用内部类最吸引人的原因是:每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。也就是说内部类允许以继承多个非接口类型(类或者抽象类)的方式来实现“多重继承”。匿名内部类Object object = new Object() . ; 以上代码创建了一个继承自Object的匿名内部类的对象。如果初始化匿名内部类的成员变量,可以直接在变量定义的后边初始化,也可以使用类似于构造器的方法初始化实例初始化块(匿名内部类没有名字,所以也不可能有构造器)。但在初始化时,如果匿名内部
26、类需要用到外部方法中的变量(外部方法的形参或者外部方法的局部变量),那么外部方法中的该变量必须声明为final的。同时注意:匿名内部类既可以继承类,也可以扩展接口,但是不管是什么,一次只能一个啊。静态类 静态类包含在外部类中,但用static修饰,在实例化时不需要有外部类的实例。重载与覆盖java中,派生类可以随意重载基类中已经拥有的方法,并且使用基类中已经拥有的方法和使用自己重载的方法一样容易,但是如果你想覆盖基类中的方法时最好加上注解:Override,以防止弄错了,没有覆盖,反而成了重载。注意方法的类型由方法名和参数列表和参数类型组成,方法返回值和方法名后边跟的异常说明不属于方法类型的一
27、部分。组合与继承组合:就是在类中定义其他类的引用,并使用之。继承:声明形式为:public class child_name extends father_name 在面向对象的编程中,要谨慎使用继承,因为继承可能会导致脆基类问题,也即当你更改超类时可能会破坏子类。关于应该使用组合还是使用继承,看看是否需要向上转型,如果需要则考虑使用继承,如果不需要则考虑要不要使用继承。多态java中除了static方法(构造器实际上也是static方法,只不过该static声明是隐式的)和final方法(private方法属于final方法)之外,其他所有的方法都是后期绑定。多态正是基于此机制。同时请注意,
28、对于成员变量并不具有多态性啊。接口(interface) 类可以有多个接口,接口的意义在于多态!在C+中允许多重继承,即一个子类可以有多个父类;但在Java中是不允许一个子类有多个父类的,这样也是为了简单化,防止致命方块的复杂性。接口可以用来解决多重继承的问题,却也不引起致命方块的问题。接口解决致命方块的方法很简单:那就是把全部的方法设置为抽象的,就相当于100%的纯抽象类。接口允许创建者确定方法的名字、参数、以及返回类型,但是没有任何方法体,以分号结束。接口也可以包含域,但是这些域隐式的是static和final的。静态类也可以作为接口的一部分,放到接口中的任何类都自动地是public和st
29、atic的。接口的定义: public interface Pet ,定义Pet类为接口。接口的实现: public class Dog extends Animal implements Pet ,Dog继承自Animal,以Pet为接口。注意:一个实现该接口的具体类必须实现该接口中的所有方法。枚举(enum)暂时还没东东呢类型信息Java允许运行时识别对象和类的信息,运行时类型信息识别主要有两种方式:RTTI、反射(折射折射你在哪儿)。RTTI: 通过RTTI(Run-Time Type Information,运行时类型信息),程序能够使用基类的引用来检查这些引用所指的对象的实际派生类型
30、。同时注意:RTTI实际上允许我们对特定的类进行特定的处理,这对于有过程化编程经验的程序猿来说,是不是很合口味?但是我们在面向对象的编程中,应该尽量使用多态机制,来进行普适操作,然而使用多态机制要求你对基类拥有控制权。因此对于RTTI和多态要进行合理取舍。Java的RTTI与Class对象密切相关。Class: Class是java中的一个类(java.lang.Class),只不过名字有点特殊罢了。那么这个类抽象了什么?它的实例又表示了什么呢?在一个运行的程序中,会有许多类和接口存在。我们就用Class这个类来表示对这些类和接口的抽象,而Class类的每个实例则代表运行中的一个类。所谓抽象,
31、就是提取这些类的一些共同特征,比如说这些类都有类名,都有对应的hashcode,可以判断类型属于class、interface、enum还是annotation。 需要注意的是,这个特殊的Class 类没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的,因此不能显式地声明一个Class对象。 虚拟机为每种类型管理一个独一无二的Class对象。也就是说,每个类(型)都有一个Class对象。运行程序时,Java虚拟机(JVM)首先检查是否所要加载的类对应的Class对象是否已经加载。如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入。 基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也都对应一个 Class 对象。 每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。 一般某个类的Class对象被创建,它就用来创建这个类的所有对
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1