一:Java基础
1:Java有什么优势
Java适合于写软件,有封装、继承、多态、跨平台(生成.class文件,二进制级别)的优点。
2:基本名词
(1):JVM 虚构一个计算机,通过在实际的计算机上模拟仿真实现各种计算机的功能。JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在JVM上可以运行的目标代码(字节码),所以可以不加修改的在多个系统上运行。
(2):JDK Java开发工具包,是Java的核心,包括了JRE、Java工具、Java基础类库。
(3):JRE Java的运行环境(可能会问JDK和JRE的区别)。
(4):GC Java中的垃圾回收机制,不必担心内存泄漏。
3:OOP(面向对象编程)
(1):继承 Java中没有多继承,要用接口(一个类可以实现多个接口)或者间接继承实现;子类会继承父类所有非私有属性和方法。
(2):向上转型 父类引用可以指向子类对象,父类引用无法调用子类的非重写方法(父类是子类的,子类的不是父类的);接口引用可以指向实现类对象,接口引用无法调用实现类的非重写方法。
(3):重载与重写
a. 重载:在同一个类的内部,函数名相同但是参数列表不一样(参数的个数不一样或者参数的类型不一样)的多个方法就构成了重载方法。
b. 重写:在子类中拥有与父类同名的方法。只有遵循了“两同两小一大”规则的方法才构成重写。
“两同”指的是方法名相同,形参列表相同;
“两小”指的是子类方法的返回值应该比父类方法的返回值类型相同或者更小,子类方法声明抛出的异常类型应该比父类抛出的异常更小或者相同;
“一大”指的是子类方法的访问权限应该比父类的访问权限相等或者更大
(4):this和super的用法
a. this关键字:是自身的一个对象,代表对象本身,可以理解为指向对象本身的一个指针,必须在非静态方法中使用(因为静态方法属于类,而非示例对象)
b. super关键字:可以理解为是指向自己超(父)类对象的一个指针,而这个超类指的是离自己最近的一个父类;调用父类中的某一个构造函数(应该为构造函数中的第一条语句);子类与父类的成员变量同名,引用成员变量。
(5):接口和抽象类的区别
抽象类是单继承,接口是多重实现。
接口中无构造方法,抽象类可有构造方法。
在抽象类中,可以有自己的数据成员,也可以有非 abstract的成员方法;而在接口方式的实现中,只能有static final数据成员(不过在interface中一般不定义数据成员),所有的成员方法都是abstract的。
接口的方法都是public的,但抽象类可以有protected或是private的方法。
(6):static static关键字可以修饰成员变量和方法,来让它们变成类的所属,而不是对象的所属
调用方式:static可以使用"类名.成员"来调用;
存储位置:static成员是所有对象的共享数据,存储在方法区(共享数据区)的静态区;普通成员储存在堆内存的对象中;
生存周期:static成员随着类的加载而存在随着类的消失而消失,而普通成员随着对象创建和回收而存在和释放;
静态使用时需要注意的事项:
1.静态方法只能访问静态成员。(非静态既可以访问静态,又可以访问非静态);
2.静态方法中不可以使用this或者super关键字【this和super属于对象】。
静态代码块:随着类的调用或创建实例而执行,而且只执行一次。用于给类进行初始化。
(7):final
A. 被final修饰的类,不能被子类继承。【因此一个类不能既被abstract声明,又被final声明】;
B. 被final修饰的方法,在使用的过程中不能被修改,只能使用,即不能方法重写;
C. 被声明为final的变量必须在声明时给出变量的初始值,使用的过程中不能被修改,只能读取。
二:编码规范
1:命名
变量和方法名驼峰命名法,第一个单词的字母全部小写,从第二个单词开始首字母大写其他字符小写
2:文档注释
(1)开头处:说明作者、时间、版本、要实现的功能的描述等信息
/**
*类的功能说明
*@author he
*@version 1.0
*@since JDK1.0
*/
(2):方法注释
/**
*这个方法是输出......
*@param 对变量进行说明
*@return 对返回值进行说明
*@throws 对抛出的异常的类型进行说明
*/
(3):生成文档注释
通过Javadoc工具,可以很方便的将源代码中的注释转换为HTML文档说明。
操作步骤:在project下找到generate javadoc,在configure中加入JDK下bin里的javadoc.exe路径,即可生成在选定目录。
3:快捷键的使用
Eclipse的编辑功能非常强大,掌握了Eclipse快捷键功能,能够大大提高开发效率。Eclipse中有如下一些和编辑相关的快捷键。
1)【ALT+/】当记不全类、方法和属性的名字时,多体验一下【ALT+/】快捷键带来的好处吧。
2) 【Ctrl+/】快速添加注释,能为光标所在行或所选定行快速添加注释或取消注释。
3)【Ctrl+D】删除当前行,不用为删除一行而按那么多次的删除键。
4)【Ctrl+Shift+B】在当前行设置断点或取消设置的断点。
三:JDK API
1:经常使用的库
为维护和使用方便,类库按包结构划分经常使用的包:
(1)java.lang 基础库,如字符串、多线程等,使用频率高,不用导入包。
(2)java.io 文件操作、输入输出。
(3)java.util 常用工具包,如集合,随机数产生器,日历,时钟。
(4)java.net 网络操作。
(5)java.security 安全相关操作(明文传输比较危险)。
(6)java.text 处理文字、日期、数字、信息的格式。
(7)java.sql 数据库访问。
2:核心API
(1)日期操作
a. Date以及常用API
Java中的时间:使用标准类库的Date类表示,是用距离一个固定的时间点(UTC时间1970年1月1日00:00:00)的毫秒数(可正可负,long类型的)表达特定的时间点。
Date类简介: java.util.Date类封装日期以及时间信息,常用方法为setTime以及getTime,Date类的大多数用于进行时间分量计算的方法已经被Calendar取代。
Date date = new Date();
//获取系统当前时间以及时间信息
long time = date.getTime();
//从1970年1月1日到现在所经过的毫秒数,long类型
b. SimpleDateFormat
java.text.SimpleDateFormat是一个以跟语言环境有关的方式来格式化和解析日期的具体类。这个类允许进行格式化日期文本,也允许解析文本日期和规范化
构造方法:
SimpleDateFormat()
SimpleDateFormat(String pattern) 用给定的模式和默认语言环境的日期格式符号构造 SimpleDateFormat方法
final String format(Date date) Date->String
Date parse(String source) throws ParseException String->Date
将String格式化为Date:
String str="2012-12-12";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf.parse(str);
println(date);
c. Calendar类: java.util.Calendar类是用于封装日历信息,其主要作用在于其方法可以对时间分量进行计算
Calendar是抽象类,其具体子类需要针对不同国家不同地区的日历系统。其中应用最广泛的是GregorianCalendar(格里高里历,也就是通用的阳历),对应世界上绝大多数国家以及地区使用的标准日历系统。
getInstance方法:该方法获取Calendar类型的一个通用对象,该方法返回一个Calendar对象,其日历字段已经由当前日期和时间初始化。
Calendar c = Calendar.getInstance();
GregorianCalendar c1 = new GregorianCalendar(2017,Calendar.March,...) //月份要用类里面定义的静态常量
int getActualMaximum(int field) 给定次Calendar的时间值,返回指定日历字段可能拥有的最大值
(2)集合操作
Collection:在实际开发中,需要将使用的对象存储于特定的数据结构的容器中。JDK就提供了这样的容器--Collection(集合)。
Collection是一个接口,定义了集合相关的操作方法,其有两个子接口:List和Set。
List:可重复集, Set:不可重复集(调用equals()方法比较的结果判断元素是否重复)。
java.util中共有13个类可用于管理集合对象,它们支持集、列表或映射等集合,以下是这些类的简单介绍
a.集合Set:
HashSet: 使用HashMap的一个集的实现。虽然集定义成无序,但必须存在某种方法能相当高效地找到一个对象。使用一个HashMap对象实现集的存储和检索操作是在固定时间内实现的。
TreeSet: 在集中以升序对对象排序的集的实现。这意味着从一个TreeSet对象获得第一个迭代器将按升序提供对象。TreeSet类使用了一个TreeMap。
b.列表List:
Vector: 实现一个类似数组一样的表,可自动增加容量。使用下标存储和检索对象就象在一个标准的数组中一样,也可以用一个迭代器从一个Vector中检索对象。Vector是唯一的同步容器类,当两个或多个线程同时访问时也是性能良好的。
Stack: 这个类从Vector派生而来,并且增加了方法实现栈。
LinkedList: 实现一个链表。由这个类定义的链表也可以像栈或队列一样被使用。
ArrayList: 实现一个数组,它的规模可变并且能像链表一样被访问。它提供的功能类似Vector类但不同步。
【知识点:ArrayList和LinkedList的区别】
1.ArrayList是实现了基于动态数组的数据结构,LinkedList是基于链表结构。
2.对于get和set方法,ArrayList要优于LinkedList,因为LinkedList要移动指针。
3.对于add和remove,LinkedList比较占优势,因为ArrayList要移动数据。
c.映射map:
Hashtable: 所有的键必须非空。为了能高效的工作,定义键的类必须实现hashcode()方法和equal()方法。这个类 是前面java实现的一个继承,并且通常能在实现映象的其他类中更好的使用。
HashMap: 允许存储空对象,而且允许键是空。
ConcurrentHashMap:
WeakHashMap: 实现这样一个映象:通常如果一个键对一个对象而言不再被引用,键/对象对将被舍弃。这与HashMap形成对照,映象 中的键维持键/对象对的生命周期,尽管使用映象的程序不再有对键的引用,并且因此不能检索对象。
TreeMap: 实现这样一个映象,对象是按键升序排列的。
【知识点:HashMap和Hashtable有什么区别?】
HashMap允许键和值是null,而Hashtable则不允许键或者值是null。
Hashtable是同步的,而HashMap不是,所以HashMap更适用于单线程环境,Hashtable则适用于多线程环境。
四:字符串
1:String
String为不可变对象(字符串一旦被创建,对象永远无法被改变,但是字符串引用可以重新赋值)。
(1) String常量池:java为了提高性能,将所有静态字符串(字面量、常量、常量连接的结果)在常量池中创建,并尽量使用同一对象,重用静态字符串。对于重复出现的字符串,JVM首先在常量池中查找,如果存在则返回对象。
(2) 内存编码:采用unicode编码,任一字符对应两个字节的定长编码(可以表示中文)。
(3) 常用API :
a.判断字符内容是否相同
boolean equals(str):复写了object类中的equals方法。
boolean.equalsIgnorecase(str):判断内容是否相同,并忽略大小写。
compareTo(str) :按字典序比较两个字符串,返回第一个不相同字符的字典序之差。
== 比较的是地址,而非内容;equals比较的是内容。
b. 类型转换
将字符数组转成字符串:
构造函数:String(char[])
String(char[],offset,count) 将字符数组中的一部分转成字符串
静态方法:
static String copyValueOf(char[]);
static String copyValueOf(char[] data,int offset,int count); 将字符数组中的一部分转成字符串。
将字符串转成字符组:
char[] tocharArray();
将字节数组转成字符串:
String(byte[])
String(byte[],offset,count):将字节数组中的一部分转成字符串。
将字符串转成字节数组:
byte[] getBytes()
将基本数据类型转成字符串:
static String valueOf(int/double),调用时可直接用String.valueOf(number)
2:StringBuffer和StringBuilder
String为不可变对象(字符串一旦被创建,对象永远无法被改变,但是字符串引用可以重新赋值),而StringBuffer和StringBuilder封装可变字符串,需要修改字符串时用。两者的用法相似,区别在于StringBuilder线程不安全,但速度快,而StringBuffer可使用在多线程中。
StringBuffer类中的方法主要偏重于对于字符串的变化,例如追加、插入和删除等,这个也是StringBuffer和String类的主要区别。
【知识点:java string对象 “+”和append链接两个字符串之间的差异】
String +号拼接的原理是会在底层new一个StringBuilder,重新开辟一段内存,再调用append操作,而StringBuilder和StringBuffer直接append,效率比String的+高得多。
public StringBuffer append(各种类型的数据 ):追加内容到当前StringBuffer对象的末尾,类似于字符串的连接。
public StringBuffer deleteCharAt(int index) : 删除指定位置的字符,然后将剩余的内容形成新的字符串。
注意:StringBuilder的很多方法的返回值均为StringBuilder类型,方法的返回语句均为:return this;由于返回的都是当前对象,所以会在程序中看到一种简洁的书写方式:
str.append("softi").append("java").insert(1,"oracle").replace(0,4,"softi.com");
五:类
1:Object类
(1)概念:在Java的继承中,java.lang.Object类位于继承的顶端,如果定义一个Java类时没有使用extends关键字声明其父类,则其父类默认为java.lang.Object。 Object类型的引用变量可以指向任何类型对象。
(2)toString方法:原则上建议每个类都重写toString方法,格式上大多数遵循"类的名字[域值]",如果不重写,将使用Object类的toString方法,其返回值为:类名@散列码。
Object类中的toString方法返回对象值得字符串表示;
Java中很多地方会默认调用对象的toString方法:字符串+对象 自动调用对象的toString方法;System.out.print(任意对象) ,会自动调用对象的toString方法;
toString方法是非常有用的调试工具。JDK中的标准类库中,许多类都定义了toString方法,方便用户获取相关对象状态的必要信息。
(3)equals方法: Object类中的的equals方法用于检测一个对象是否等同于另一个对象,在Object类中,这个方法判断两个对象是否具有相同的引用,即是否指向相同的对象。
在实际应用中,一般也需要重写该方法,通过比较对象的成员属性,使该方法更有意义。
2:包装类
(1)概念
Java中的八种基本数据类型byte,char,short,int,float,long,double,boolean都是以值的方式保存于内存中,而不是保存在对象中。它们不是Object的子类,所以不能参与面向对象的开发。包装类(wrapper)就是用来将基本数据类型转换成相应对象的一种特殊类。包装类是不可改变的类,在构造了包装类对象之后,不允许更改包装在其中的值。包装类是final的,所以不可以有子类。
基本类型 包装类 父类
int java.lang.Integer Number
long Long Number
double Double ...
short Short
float Float
byte Byte
char Charcter Object
boolean Boolean Object
(2)用法
Number类及其主要方法:抽象类Number是Integer,Long,Double,Short,Float,Byte类的父类,Number类的子类必须提供将表示的数值转换成对应的类型的方法。
intValue() 以int的形式返回指定的数值。
Integer常用方法:
该类提供了int类型和String类型之间进行转换的方法,并且提供了一些常量。
static int MAX_VALUE 2^31 - 1的常量,表示int类型的最大值。
static int MIN_VALUE -2^31。
Double常用方法:
构造方法:
Double(double value)
Double(String s)
常用方法:
double doubleValue() 返回此对象的double值;
static double parseDouble(String s) 返回一个新的double值,该值被初始化为指定的String表示的值;
Double.parseDouble("123.54")
Double.parseDouble("¥123.54") 这么调用时会抛出NumberFormatException异常
(3)自动装箱以及自动拆箱操作(autoboxing)
该功能是从Java5.0之后加入的,自动装箱和拆箱是JDK5的编译器在编译器的“预处理”阶段进行的工作
Integer a = 100;//装箱
Integer b = 200;
Integer c = a + b;//拆箱然后装箱
装箱跟拆箱是编译器进行的工作,而不是JVM。编译器会在生成类的字节码时会插入必要的方法调用:Integer a = 100 =>Integer a = Integer.valueOf(100);
注意:当包装类作为方法的参数时,eg:void takeNumber(Integer i){ },实际调用该方法时传递Integer类型或者int类型的参数都可以。
六:异常
异常分类: 可查异常(自己捕捉),运行时异常(数组越界、除0等,不是必须进行捕捉)和错误(系统级别的异常)3种。
【知识点:throw和throws的区别,Error和Exception的区别】
运行时异常与非运行时异常的区别:运行时异常是不可查异常,不需要进行显式的捕捉;非运行时异常是可查异常,必须进行显式的捕捉,或者抛出。