字符串缓冲类 (StringBuffer)
String对象声明的变量一旦生成,其内容是不可变的,StringBuffer对象的变量的长度是可以变化的,可以插入,扩充等其他操作。每个字符串缓存都有一定的容量,只要字符串缓存存储的字符序列得长度没有超过它的容量,就无须申请新得内部缓冲数组,如果内部的缓冲区溢出,它将自动加以扩大。
对象:指具有属性和动作的实体
类得定义
[类修饰符] class ClassName
类修饰符只能是public 或没有类修饰符,public,private,protected等是变量和方法的修饰符
类中变量和方法的访问权限,public,protected,private,缺省
访问权限 同一类中 该类的子类 同一包中 其他包
Public 可以 可以 可以 可以
protected 可以 可以 可以 被子类继承访问
缺省 可以 可以 可以 不 可以
private 可以 不可以 不可以 不可以
当在类定义中用public关键字类类修饰时,在保存此类时,类的文件名必须和类名一致,当不用public来修饰时,类的文件名和类名可以不一致,建议保存此类的文件名保持一致
成员变量和局部变量得作用范围
成员变量再整个类内部有效,局部变量只在其定义得方法内部有效。
成员变量分为:实例成员变量和类成员变量
在成员变量定义之前加上static关键字,那么此成员变量就是类成员变量或静态成员变量。
Class variableDemo
{
int intvariable; //实例变量
static float intvariable; 类变量
}
成员变量得分类
当定义的局部变量的名字和成员变量的名字相同时,则成员变量被隐藏,使用的是局部变量。要使用成员变量,必须通过关键字this来引用。
方法的重载
方法的重载是指一个类可以有多个方法具有相同的名字,但这些方法的参数必须不相同,不同之处可以是参数得类型和参数的数量。
类的重载方法的判断只和方法的参数的类型和数量相关,与方法返回的值得类型无关
如果子类重写父类的方法,那么返回类型和参数等必须相同
构造方法
构造方法通常用来完成对象得初始化工作
构造方法是一种特殊的方法,名字必须与其类得名称完全相同,并且不返回任何数据类型,即void类型,但void必须不写。
Main方法
public static void main(String args[] )
args为参数
输入参数:
java mainDao 第一个参数 第二个参数 第三个参数
垃圾回收器原理:
当不存在对一个对象得引用时,就假定不需要该对象了,那么就可以回收该对象所占有得内存。在java中并不需要明确地销毁对象,垃圾收集仅在程序执行时偶尔出现,其不会因为一个或几个存在得对象不再被使用而发生。
和对象清楚相关得方法两个:finalize(), gc()
Finalize():方法是object类的方法,任何一个类都从object继承了这个方法,finalize()方法是再对象被当成垃圾从内存中释放前调用,而不是在对象变成垃圾前调用,垃圾回收器的启动不由程序员控制,也无规律可循,并不会一产生垃圾就被唤起,甚至有可能到程序终止它都没有被启动,因此这并不是一个很可靠的机制,所以,我们无法保证每个对象的finalize()方法最终都会被调用。
垃圾回收器只知道释放那些由new分配的内存。一旦垃圾回收器准备回收new对象,将首先调用finalize()方法,该方法能在垃圾回收时刻做一些清理工作。
这意味着在你不需要某个对象之前,如果必须执行某些动作,那么你得自己去做(finalize()方法)。通常不能指望finalize(),必须创建其他的"清理"方法,并且明确的调用它们。finalize()作用:对象"终结条件"的验证。
源文档 <http://luxhua.iteye.com/blog/379790>
Java的垃圾回收器执行的偶然性有时候也会给程序运行带来麻烦,如果不及时释放垃圾占用的内存,就可能有问题,
java提供的System.gc()方法可以强制启动垃圾回收器来回收垃圾,就像主动给环卫局打电话,通知他们来清理垃圾一样。
匿名对象是指在生成对象时没有指定名字的对象,使用匿名对象的两种情况;
1.如果对一个对象只需要一次调用,就可以使用匿名对象
2.将匿名对象作为实参传递给一个函数
方法中参数的传递
1.按值传递
把实参的值复制后被传递给形参,故方法中对形参的改变不会影响实参的值
2.引用传递
将一个实参的引用(不是参数的值)传递给方法中的形参,这意味着对参数的改变将会影响传递给方法的实参的值
继承 extends
子类继承父类数据成员和方法关系图
Public ,protected,private非类的修饰符,(类只有public,和没有修饰符,内部类除外)
同一个包中 包1 包2
父类 子类 父类 子类
public类型 public类型 public类型 public类型
protected类型 protected类型
protected类型 protected类型
友好类型
友好类型 友好类型
private类型
private类型
覆盖
覆盖是指子类拥有和父类系统的成员
成员变量的覆盖:子类中定义的成员变量和父类中的成员变量同名
成员方法的覆盖:子类中定义的成员方法和父类中的成员方法在方法名,返回类型,参数个数以及类型都相同
覆盖可以隐藏父类中的成员变量和方法,覆盖的目的通过在子类中重新定义的变量和方法来扩展父类的功能
覆盖遵循的原则:
覆盖方法的返回类型必须与它所覆盖的方法相同
覆盖方法的参数类型和参数个数与它所覆盖的方法相同
覆盖方法不能比其所覆盖的方法访问权限低
覆盖方法不能比所覆盖的方法抛出更多的异常
抽象类
抽象类不能创建对象,而只能由其派生的子类创建,抽象类是专门作为其他类的父类来使用的。
抽象类必须作为其他类的父类,并且子类要全部实现父类中的抽象方法
抽象方法只能有方法的声明,不能有方法的具体实现,包含抽象方法的类叫抽象类
抽象类的定义
abstract class ClassName { }
或
public abstract class ClassName { }
抽象方法的定义
abstract returnType metnodName()
例子:
abstract protected float getArea();
或
protected abstract float getArea();
接口
在java接口中,所有的方法都是抽象的方法,所有的变量都是static常量,就算在定义的时候没有声明变量为static,系统也会自动添加final static,方法自动添加abstract
语法:
interface 接口名
{
}
实例:
interface MyInterface
{
static final int max=10; 定义一个常量
int mix=20; 系统会自动的为min添加 static final 修饰符
abstract void method();// 声明一个抽象的方法
float sum(float x, float y) 系统会自动的为该方法添加abstract 修饰符
接口的使用
一个类通过关键字implements声明自己使用一个或多个接口,若使用多个接口,接口之间用逗号隔开
class className implements interface1,interface2
接口中的方法全部是抽象方法,故实现此接口的类必须实现接口中的所有方法,要在类中实现接口的方法,方法的名字,返回类型,参数个数及类型必须和接口中的完全一致。
接口实现的几点说明:
接口中的方法默认都是public类型的,故类在实现接口中的方法时,必须用public修饰
若接口中方法的返回来类型不是void,那么在类中实现该接口的方法时,方法体至少要有一个return语句
接口声明时,如果关键字interface前面加上了public关键字,用Public修饰的接口可以被任何一个类使用,如果一个接口不加public修饰,这样的接口称为友好接口,友好接口可以被同一个包中的类使用
利用关键字extends,一个接口可以继承另一个接口,其语法与继承类时的语法相同,当一个类实现了一个接口,而该接口继承了另一个接口时,此类必须实现所有接口中的方法。
内部类
在一个类的内部定义另一个类,这种存在于一个类内部的类被称为内部类
内部类分为:静态类,成员类,局部类和匿名类
匿名类(anonymous class)
匿名类没有明确的类定义格式,是指该类的定义和类对象的创建合并在一起的情况。
interface Inner
{
public void method();
}
public class AnonymousClass {
public static void main(String args[])
{
Inner obj=new Inner()
/*匿名类开始*/
{
public void method()
{
System.out.println("匿名类中实现接口的方法");
}
};
/*匿名类结束*/
obj.method();
}
}
在生成接口对象obj同时定义了匿名类,并实现接口中方法method()
在匿名类的创建可知,匿名类属于一个唯一的对象,如上面的匿名类属于对象Obj
静态类(static class)
静态类作为类的静态成员存在于某个类中,要定义一个静态类只需要在类的定义中加入关键字static即可。
列子:
class outerClass
{
static class Innerclass
{
}
}
当在类OuterClass中定义了一个静态类Innerclass后,可以将此静态类Innerclass看做是类Outerclass的static成员,即在不创建类OuterClass对象的情况下,直接创建静态类InnerClass的对象。
在类OuterClass内部,创建静态类InnerClass对象的代码如下:
Innerclass obj=new Innerclass();
在OuterClass外部,创建静态类InnerClass对象的代码如下;
OuterClass.InnerClass obj=new OuterClass.InnerClass();
成员类(member class)
定义一个成员类和定义一个一般的类没有任何区别
class OuterClass
{
class MemberClass
{
}
}
只有创建了类OuterClass对象之后,才能创建MemberClass类
局部类(local class)
局部类和局部变量一样,是指在方法内部定义的类,局部类的定义和一般类的定义类似。
例如:
class OuterClass
{
void method( ) //类OuterClass的成员方法
{
class LocalClass //成员方法中定义局部类LocalClass
{
}
}
}
局部变量定义仅在方法内部使用,方法执行完毕后,其就会消失,同样,局部类也是在方法内部才可以创建对象,一旦方法执行完毕,其就会消失。
类的其他修饰符:final static this super
final修饰符
.final 可用于修饰类,成员变量,成员方法
1.final修饰类
如果类在定义时,加上了final修饰符,说明该类是最终类,不能被作为父类进行继承,
例如:
final class FinalClassDmo
{
}
2.final修饰变量
final修饰的变量是最终变量,即常量,java中的常量可以被访问,但不能被修改其值,如下:
final type variableName=initValue;
final int max=20;
3.final 修饰方法
用final修饰的方法称为最终方法,继承包含最终方法的类的子类不能覆盖该最终方法,即子类不能对父类中的最终方法进行修改
final returnType methodName ()
final int method()
{
}
static修饰符
static修饰符用来修饰类中的变量和方法,用static修饰的成员变量称为静态变量或类变量,用static修饰的成员方法称为静态方法或类方法。
1.static修饰变量
static修饰的变量称为类变量,不用static修饰的变量称为实例变量
类变量在类被加载到内存中时,就被分配内存空间,而实例变量只有在生成类对象时,才分配内存空间
class StaticDmeo
{
static int a; 定义一个类变量、
int b;
public static void main(String args[])
{
生成两个StaticDemo对象
StaticDemo obj1=new StaticDemo();
StaticDemo obj2=new StaticDemo();
obj1.a=10;
obj1.b=20;
obj2.a=15;
obj2.b=25;
System.out.println("对象obj1中变量a的值为" +obj.1a);
System.out.println("对象obj1中变量b的值为" +obj1.b);
System.out.println("对象obj2中变量a的值为" +obj2.a);
System.out.println("对象obj2中变量a的值为" +obj2.b);
结果为:
15
20
15
25
从结果中可以看出不同对象的静态变量a共享同一块内存空间,因此其值相等,而实例变量b,不同的对象有不同的内存空间
2.static修饰方法
在类中使用static修饰的方法称为类方法,而不被static修饰的方法称为实例方法,类方法在类被加载到内存中时,就被分配到内存空间,而实例方法只有在生成类对象时,才分配内存空间
类方法中不允许使用类中的实例变量,只能使用类中的类变量,而实例方法既可以使用类变量,也可以使用类中的实例变量。
this关键字
this关键字指对象自身的引用,即类本身。
super关键字
super关键字指明了是对父类的引用,当一个子类中的变量和方法同父类的成员变量和方法完全相同时,则父类中的成员变量和方法将被隐藏,不能被子类继承,如果想在子类中使用被其覆盖的父类的成员变量和方法时,就可以使用关键字super.
集合工具类 (collections )
所有的集合工具类都只能存放对象而不能存放基本数据类型,java5.0以后支持自动装箱,可以把基本数据类型自动封装成相关对象
常用的集合工具类的关系图
1.Collection与Map的区别是Collection中存放对象时时一个一个的放置,而Map时一对一对的放置
2.List与Set的区别是:List存放的对象是有位置顺序的,而set没有。由于List中的对象有位置差异,因此允许有重复,Set中不允许有重复,set中存放的元素是无序的
3.ArrayList与Vector的主要区别是ArrayList不是线程安全的,如果不加特别处理,多个线程使用同一个ArrayList会出现差错,而Vector不会,Vector是线程安全的
4.HashMap与Hashtable的主要区别是HashMap不是线程安全的,而Hashtable是线程安全的
两个通用Set实现是HashSet 和TreeSet。要决定用哪一个,那是非常简单明了的。 HashSet 要快得多 (对大多数操作是常数时间之于对数时间(constant time vs. log time)), 但不提供排序保证。如果你需要使用 SortedSet 中的操作,或者按顺序迭代对你来说是重要的,那么请使用 TreeSet。 否则,使用 HashSet。 在大多数时间都不使用 HashSet
关于 HashSet,有一件事应该牢记,即就条目数和容量之和来讲,迭代是线性的。因此,如果迭代性能很重要,那就应该慎重选择一个适当的初始容量。容量选得太大,既浪费空间,也浪费时间。 默认的初试容量是101, 一般来讲,它比你所需要的要多。可以使用 int 构造函数来指定初始容量。要分配 HashSet 的初始容量为17:
Set s= new HashSet(17);
HashSets 另有一个称作 装载因数(load factor) 的"调整参数(tuning parameter)" 。如果你非常在乎你的 HashSet 的空间的使用,请阅读 HashSet 文本以获取详细信息。否则,就使用默认值吧。如果你接受默认装载因数,但你确实又想指定初始容量,那么,选一个大约是你期望你的 Set 将增长到的容量的两倍的数。如果你的猜测不着边,它也可以增长,或只是浪费一点空间。但都没有大问题。如果你知道有关正确尺寸的一个最佳值,用它吧;如果不知道,那就使用一个旧的值,或使用一个偶数值。它真的不是非常重要。这些事情只能使 HashSet 稍稍变好一点点。
TreeSet 没有调整参数。除 clone 之外,HashSet 和 TreeSet 都仅有那些由它们各自的接口所要求的操作 (Set 和 TreeSet),而没有任何别的操作。
源文档 <http://topic.csdn.net/t/20040402/15/2918089.html>
向量表 (ArrayList)
向量表实现接口List,因此里面存放的是彼此独立的元素,这些元素在ArrayList里按位置存放,通过位置可以索引出该位置的元素
与数组不同,ArrayList没有容量的限制,ArrayList默认的容量为10,当容量用尽的时候,ArrayList会自动扩大容量,ArrayList自动以50%的容量速度扩展。
游标 (Iterator)
游标提供了遍历集合类的另一种方式,不必关心ArrayList,还是Vector或Set,只要支持游标操作,就通过游标遍历该集合类
List list=new ArrayList(2);
list.add("IBM');
list.add("microsoft");
for(Iterator it=list.iterator();it.hasNext();)
{
Object obj=it.next();
System.out.print(obj);
}
向量(Vector)
向量是另一种形式的列表,vector相对于ArrayList最重要的特征就是Vector是线程安全的
Vector的容量也是自增的,当容量用完的时候,Vector以100%容量的速度递增
哈希集合(HashSet)
存放的元素是无序的,特性与Set一样,之所以叫哈希,是因为使用哈希算法来快速存取元素的
实现了set接口
哈希映射(HashMap)
实现了Map接口
哈希表(Hashtable)
哈希表也是一种Map,与哈希映射相比最大的特点是它是线程安全的,Hashtable可以直接用在多线程里面而不会出错,也是使用的哈希算法,由于内部加入了线程同步机制,因此Hashtable的速度要比HashMap稍微慢些,另外,Hashtable中key与value都不允许为null值,而HashMap允许
异常
java提供了处理此类异常的接口:Throwbale
所有的异常情况被封装成了Throwable类或者该类的子类,所有的异常类型都是Throwable的子类
Throwable有两个直接的子类:
1.一个是Exception,是用户程序能够捕捉的异常情况,可通过继承Excption或其子类来创建自己的异常
2.Error,它定义了那些通常无法捕捉到的异常,一般来说,Error子类通常会导致灾难性的失败
错误类由Error作为顶层,Error定义了在通常环境下不希望被程序捕获的异常,Error类型的异常用于java运行时系统来显示与运行时系统本身有关的错误,如堆栈错误
Exception又分为两种:
1.RuntimeException 是不需要检查的异常,这些异常在编译过程中是不需要检查的,也不需要添加到任何方法的 throws列表中,比如NullPointerException
2.普通的Exception 需要检查的异常
捕捉异常
try
{
}
catch()
{
}
finally{
}
catch(),finally都是可有可无得,但是catch和finally必须至少有一个存在。
为什么有的方法需要捕捉异常,而有的方法不需要捕捉异常
原因在于,那些需要捕捉异常的方法都抛出了一个需要检查的异常
方法名后面用throws声明了该方法可能会抛出的需要检查的异常,如果可能会抛出多个异常,则用逗号隔开
private synchronized void readObject (java.io.ObjectInputStream s) throws IOException,ClassNotFoundException{ }
当调用一个使用throws异常的方法,比如上面的readObject时,编译器会要求写一个try…catch来捕捉这个异常,或者把调用这些方法的那个方法也用throws声明为可能抛出同样的异常
知道了为什么有些方法需要捕捉异常的原理了,就可以使自己的方法也抛出一个异常,让调用该方法的人去捕捉,只需要在方法声明后加一个throws,然后跟着一个或者多个异常类的名称就可以了。然而只是这样做是不行的,这样只是声明了可能会抛出异常,让调用该方法的人留意,但是这个异常是永远不会抛出去的
然后就在方法内部检查条件,如果不符合程序继续运行的条件,就会抛出一个一出来来,方法是用throw关键字后面跟一个异常对象,
例如:检查文件的不存在
if (!file.exists())
{
throw new IOException ("文件不存在");
}
throws与throw区别
方法名后面声明被抛出的异常类列表用的是throws关键字,而方法内部抛出异常对象用的是throw关键字
public Test() throws RepletException {
try {
System.out.println("Test this Project!")
}
catch (Exception e) {
throw new Exception(e.toString());
}
}
throws是用来声明一个方法或类可能抛出的所有异常信息
throw则是指抛出的一个具体的异常类型,用在方法的内部。
通常在一个方法(类)的声明处通过throws声明方法(类)可能抛出的异常信息,而在方法(类)内部通过throw声明一个具体的异常信息。
throws通常不用显示的捕获异常,可由系统自动将所有捕获的异常信息抛给上级方法;
throw则需要用户自己捕获相关的异常,而后在对其进行相关包装,最后在将包装后的异常信息抛出
自定义异常类型
可以根据需求确定自定义的异常为需要检查的异常还是不需要检查的异常,如果需要检查,则可以继承Exception,如果不需要检查,则可以继承RuntimeException。
java语言中进行文件读写是采用流的方式,另外,计算机与计算机与显示器,打印机等I/O设备进行的I/O交互也是采用流的方式
File可以代表文件也可以代表文件夹,它主要用来获取文件的一些信息,比如文件的位置,是文件还是文件夹,存在与否,大小,最后修改的时间等。该类不可以打开任何文件,也不提供任何处理文件内容的功能
注意:构造一个File对象不等于在硬盘上创建文件,仅仅创建File对象操作不对硬盘文件系统有任何影响。
FilenameFilter用来过滤一下不需要的文件,例如过滤掉.txt文件等。
文件的创建
使用File.createNewFile()方法创建文件,创建成功后返回true,创建失败则返回false
创建文件的时候,该文件或文件夹的父文件夹必须存在,否则会因路径找不到而抛出IOException异常
文件夹的创建 File.mkdir(),创建成功则返回false
文件的删除和更名
文件的删除和文件夹的删除都使用File.delete(),删除成功返回true
文件的更名File.renameTo(File dest)方法
File类只能对文件进行一些简单的操作,比如取属性,创建删除等,并不支持文件内容的读写,要想对文件进行读写操作,就必须通过Stream来完成
流(Stream)
流是传递数据信息的载体
输入流是将数据从数据源传递给程序,而输出流则是将数据从程序送到期望的地方,比如显示器,文件等
最初设计的输入输出类是面向字节流的,即支持8位的字节流,分别由派生抽象类InputStream和OutputStream
InputStream,OutputStream及其子类都是面向字节的,对中文的支持较差,容易出现乱码
Reader,Writer使用的是Unicode编码方式对中文有很好的支持,不会出现乱码情况
一般来说 Sytem.in用来接收用户在标准I/O设备上的输入(一般是键盘),System.out.用来将内容输出到标准I/O设备上,如显示器
读取文件的操作
读取文件的操作有两种办法:
一种是基于字节流的InputStream,另一种是使用基于Unicode字符的Reader,InputStream一般用在读取二进制文件,比如应用程序,图片文件,媒体文件等。Reader一般用于读取文本文件,比如txt文件,Log文件等。
文件的锁定操作
使用FileLock类锁定文件,
随机访问文件类(RandomAccessFile)
文件的随机访问主要通过类RandomAccessFile来完成,它使用seek()方法从文件中的一个记录移动到下一条记录,进行读或者写,而不需要知道总共有多少个记录,它不需要把所有的记录全部加入到内存再进行读写操作,因此对访问大文件来说,这是一种资源花费少的,执行效率高的选择。
java还可以用于文件的压缩,解压等
Java的高级特性
从java5.0开始Java开始支持自动装箱(auto boxing)和拆箱(unboxing),这样使得程序开发者可以直接把int当Integer使用,或者把Integer当int使用,无需手工转换
自动装箱:把基本数据类型封装成类对象
拆箱:把类对象拆成基本数据类型
Int i=new Integer(4);
Integer j=4;
Java5.0编译器会判断等号两边的数据类型,如果左边是基本数据类型,而右边是对应的类,则类会使用形如intValue()的方法取得其基本数据类型值,如果左边是对应的类,而右边是基本数据类型,则基本数据类型会使用形如valueOf()的方法取得其对应的类对象
For/in遍历数组和集合
1.遍历数组:
例子:
String array[]={"a","b","c","d");
for (String s:array) //在for循环的括号里声明一个字符串变量,冒号表示遍历数组的所有元素,把循环当前的变量值付给 S tring类型变量s
{
System.out.println(s);
}
2.遍历集合(集合中存放的都是对象,是不能存放基本数据类型的)
public class TestFor {
public static void main(String args[]){
List list=new ArrayList();
list.add("string");
list.add("integer");
for(Object obj:list){
System.out.println(obj);
}
}
}
上面的代码只能先取到了Object类,如果List里面是String类型的数据,还得写代码String s=(String)obj进行强制转换,还可以有种更优雅的遍历方式,即范型
List <String >list =new ArrayList<String>();
list.add("string");
list.add("integer");
for(String obj:list)
{
System.out.println(obj);
}
可变参数方法
从java5.0开始支持,可变参数的方法,例如Sytem.out.printf()方法,String类的format()方法等
可变长方法的定义:
例如:formate方法
public static String format(String 。。。Args)//是三个点
定义一个可变长参数方法是在参数类型的后面加上省略号,然后加上可变长参数名,可变长参数在方法的内部变现为数组,可以使用传统的数组遍历方式来使用数组,也可以使用新特性for/in循环形式。
public static double avg(double...values)
{
double total=0;
int count=values.length;
for(double i:values)
{
total+=i;
}
return total/count;
}
协变式放回类型
协变式放回类型(covariant return types)允许在覆盖父类方法的时候,是父类方法的返回值更加具体
例如:ArrayList类的get(int index)方法返回的是Object,继承ArrayList之后即可以覆盖get方法,并修改返回值为String,因为String也是Objectde 一个子类,在java5.0之前这是不允许的
静态导入
Java5.0以后的版本支持使用静态导入(import static)导入某个类的静态方法和静态变量,在使用的时候不需要再指名类名,直接应用变量名或者方法即可,import static为新增的一个指令
例如:
import static java.lang.Math.PI;
import static java.lang.Math.sin;
范型(Generic)
类与方法都可以被泛型话,类泛型由类名后面跟上一个或多个由三角括号包含的类型变量组成;方法泛型主要体现在返回类型与方法内部
例如:
ArrayList类的泛型与方法泛型
public class ArrayList<E> extends AbstractList<E> implements List<E>,RandomAccess,Cloneable,java.io.Serializable
{
…
public E get(int index)
{
…
}
}
类泛型ArrayList<E>代表的意思是ArrayList类里存放的数据类型只能是E类型及其子类,如果不是,编译会出错
方法泛型 public E get(int index)
代表的意思是该方法返回的类型是E类型,使用的时候可以直接当做E类型使用,而不用从Object强制转换为E类型
E可以任何类型
定义一个只存放String数据类型的ArrayList
List<String> list=new ArrayList<String>();
list.add("string1");
list.add(string2");
使用多个泛型
有时容器中需要放置多个对象,比如Map中,必须是key和value两个对象成对存在的,而且这两个Object的类型还可能不一致,这时就需要使用泛型来约束
Map<String,Date> map=new HashMap<String,Date>
泛型通配符
由于通配符的不确定性,通配符只能用来进行类型安全检查,而不能用来声明具体的类泛型
List <?> list 表示List放置任何类型,不过单独使用“?”没什么用,问好一般与extends和super使用
?与extends连用表示指定类型及其所有子类
?与super连用表示指定类型及其指定类型的父类
例如:
public static void numberList (List <? Extends Number> list)
public static void deteList (List <? Super Date> list>
枚举类型 enum
枚举类型不能声明在方法的内部,而只能声明为类变量
Public enum Sex {male,pemale,unknown,};
枚举类型里的变量是实实在在的对象,可以把male,pemal,unknown看作是一种内部匿名类对象,并且它们是public(可以在Sex外部引用),static(可以由类名Sex直接引用),final(引用不修改)
ublic class Enum {
public enum Sex{male,female,unknow};
public static enum type{charman,person};
public static void main(String args[]){
System.out.println(Sex.female);
System.out.println(type.charman);
}
}
扩展枚举类型
enum同Interface,class一样是一种对象,因此它可以扩展,添加属性或者方法
enum的限制:
enum内部可以由构造方法,但不能有public的构造方法
enum内置对象间必须使用逗号隔开,声明完所有的内置对象之后用分号结束
enum内置对象必须使用声明的构造函数,否则编译错误
static enum Type {
MANAGER("经理",10000);
ASSISTANT("助理",6000); //给各枚举对象添加属性
WORKER("员工",4000);
private String name;
private double pay;
Type(String name,double pay) {
this.name=name;
this.pay=pay;
}
}
注解 (annotation)
注解是以@开头的一种标记,用来修饰包,接口,类,属性,方法和变量等。包含在注解里的信息以key=value的属性对的形式提供给程序元素
@Column(name="clumen_name")
String对象声明的变量一旦生成,其内容是不可变的,StringBuffer对象的变量的长度是可以变化的,可以插入,扩充等其他操作。每个字符串缓存都有一定的容量,只要字符串缓存存储的字符序列得长度没有超过它的容量,就无须申请新得内部缓冲数组,如果内部的缓冲区溢出,它将自动加以扩大。
对象:指具有属性和动作的实体
类得定义
[类修饰符] class ClassName
类修饰符只能是public 或没有类修饰符,public,private,protected等是变量和方法的修饰符
类中变量和方法的访问权限,public,protected,private,缺省
访问权限 同一类中 该类的子类 同一包中 其他包
Public 可以 可以 可以 可以
protected 可以 可以 可以 被子类继承访问
缺省 可以 可以 可以 不 可以
private 可以 不可以 不可以 不可以
当在类定义中用public关键字类类修饰时,在保存此类时,类的文件名必须和类名一致,当不用public来修饰时,类的文件名和类名可以不一致,建议保存此类的文件名保持一致
成员变量和局部变量得作用范围
成员变量再整个类内部有效,局部变量只在其定义得方法内部有效。
成员变量分为:实例成员变量和类成员变量
在成员变量定义之前加上static关键字,那么此成员变量就是类成员变量或静态成员变量。
Class variableDemo
{
int intvariable; //实例变量
static float intvariable; 类变量
}
成员变量得分类
当定义的局部变量的名字和成员变量的名字相同时,则成员变量被隐藏,使用的是局部变量。要使用成员变量,必须通过关键字this来引用。
方法的重载
方法的重载是指一个类可以有多个方法具有相同的名字,但这些方法的参数必须不相同,不同之处可以是参数得类型和参数的数量。
类的重载方法的判断只和方法的参数的类型和数量相关,与方法返回的值得类型无关
如果子类重写父类的方法,那么返回类型和参数等必须相同
构造方法
构造方法通常用来完成对象得初始化工作
构造方法是一种特殊的方法,名字必须与其类得名称完全相同,并且不返回任何数据类型,即void类型,但void必须不写。
Main方法
public static void main(String args[] )
args为参数
输入参数:
java mainDao 第一个参数 第二个参数 第三个参数
垃圾回收器原理:
当不存在对一个对象得引用时,就假定不需要该对象了,那么就可以回收该对象所占有得内存。在java中并不需要明确地销毁对象,垃圾收集仅在程序执行时偶尔出现,其不会因为一个或几个存在得对象不再被使用而发生。
和对象清楚相关得方法两个:finalize(), gc()
Finalize():方法是object类的方法,任何一个类都从object继承了这个方法,finalize()方法是再对象被当成垃圾从内存中释放前调用,而不是在对象变成垃圾前调用,垃圾回收器的启动不由程序员控制,也无规律可循,并不会一产生垃圾就被唤起,甚至有可能到程序终止它都没有被启动,因此这并不是一个很可靠的机制,所以,我们无法保证每个对象的finalize()方法最终都会被调用。
垃圾回收器只知道释放那些由new分配的内存。一旦垃圾回收器准备回收new对象,将首先调用finalize()方法,该方法能在垃圾回收时刻做一些清理工作。
这意味着在你不需要某个对象之前,如果必须执行某些动作,那么你得自己去做(finalize()方法)。通常不能指望finalize(),必须创建其他的"清理"方法,并且明确的调用它们。finalize()作用:对象"终结条件"的验证。
源文档 <http://luxhua.iteye.com/blog/379790>
Java的垃圾回收器执行的偶然性有时候也会给程序运行带来麻烦,如果不及时释放垃圾占用的内存,就可能有问题,
java提供的System.gc()方法可以强制启动垃圾回收器来回收垃圾,就像主动给环卫局打电话,通知他们来清理垃圾一样。
匿名对象是指在生成对象时没有指定名字的对象,使用匿名对象的两种情况;
1.如果对一个对象只需要一次调用,就可以使用匿名对象
2.将匿名对象作为实参传递给一个函数
方法中参数的传递
1.按值传递
把实参的值复制后被传递给形参,故方法中对形参的改变不会影响实参的值
2.引用传递
将一个实参的引用(不是参数的值)传递给方法中的形参,这意味着对参数的改变将会影响传递给方法的实参的值
继承 extends
子类继承父类数据成员和方法关系图
Public ,protected,private非类的修饰符,(类只有public,和没有修饰符,内部类除外)
同一个包中 包1 包2
父类 子类 父类 子类
public类型 public类型 public类型 public类型
protected类型 protected类型
protected类型 protected类型
友好类型
友好类型 友好类型
private类型
private类型
覆盖
覆盖是指子类拥有和父类系统的成员
成员变量的覆盖:子类中定义的成员变量和父类中的成员变量同名
成员方法的覆盖:子类中定义的成员方法和父类中的成员方法在方法名,返回类型,参数个数以及类型都相同
覆盖可以隐藏父类中的成员变量和方法,覆盖的目的通过在子类中重新定义的变量和方法来扩展父类的功能
覆盖遵循的原则:
覆盖方法的返回类型必须与它所覆盖的方法相同
覆盖方法的参数类型和参数个数与它所覆盖的方法相同
覆盖方法不能比其所覆盖的方法访问权限低
覆盖方法不能比所覆盖的方法抛出更多的异常
抽象类
抽象类不能创建对象,而只能由其派生的子类创建,抽象类是专门作为其他类的父类来使用的。
抽象类必须作为其他类的父类,并且子类要全部实现父类中的抽象方法
抽象方法只能有方法的声明,不能有方法的具体实现,包含抽象方法的类叫抽象类
抽象类的定义
abstract class ClassName { }
或
public abstract class ClassName { }
抽象方法的定义
abstract returnType metnodName()
例子:
abstract protected float getArea();
或
protected abstract float getArea();
接口
在java接口中,所有的方法都是抽象的方法,所有的变量都是static常量,就算在定义的时候没有声明变量为static,系统也会自动添加final static,方法自动添加abstract
语法:
interface 接口名
{
}
实例:
interface MyInterface
{
static final int max=10; 定义一个常量
int mix=20; 系统会自动的为min添加 static final 修饰符
abstract void method();// 声明一个抽象的方法
float sum(float x, float y) 系统会自动的为该方法添加abstract 修饰符
接口的使用
一个类通过关键字implements声明自己使用一个或多个接口,若使用多个接口,接口之间用逗号隔开
class className implements interface1,interface2
接口中的方法全部是抽象方法,故实现此接口的类必须实现接口中的所有方法,要在类中实现接口的方法,方法的名字,返回类型,参数个数及类型必须和接口中的完全一致。
接口实现的几点说明:
接口中的方法默认都是public类型的,故类在实现接口中的方法时,必须用public修饰
若接口中方法的返回来类型不是void,那么在类中实现该接口的方法时,方法体至少要有一个return语句
接口声明时,如果关键字interface前面加上了public关键字,用Public修饰的接口可以被任何一个类使用,如果一个接口不加public修饰,这样的接口称为友好接口,友好接口可以被同一个包中的类使用
利用关键字extends,一个接口可以继承另一个接口,其语法与继承类时的语法相同,当一个类实现了一个接口,而该接口继承了另一个接口时,此类必须实现所有接口中的方法。
内部类
在一个类的内部定义另一个类,这种存在于一个类内部的类被称为内部类
内部类分为:静态类,成员类,局部类和匿名类
匿名类(anonymous class)
匿名类没有明确的类定义格式,是指该类的定义和类对象的创建合并在一起的情况。
interface Inner
{
public void method();
}
public class AnonymousClass {
public static void main(String args[])
{
Inner obj=new Inner()
/*匿名类开始*/
{
public void method()
{
System.out.println("匿名类中实现接口的方法");
}
};
/*匿名类结束*/
obj.method();
}
}
在生成接口对象obj同时定义了匿名类,并实现接口中方法method()
在匿名类的创建可知,匿名类属于一个唯一的对象,如上面的匿名类属于对象Obj
静态类(static class)
静态类作为类的静态成员存在于某个类中,要定义一个静态类只需要在类的定义中加入关键字static即可。
列子:
class outerClass
{
static class Innerclass
{
}
}
当在类OuterClass中定义了一个静态类Innerclass后,可以将此静态类Innerclass看做是类Outerclass的static成员,即在不创建类OuterClass对象的情况下,直接创建静态类InnerClass的对象。
在类OuterClass内部,创建静态类InnerClass对象的代码如下:
Innerclass obj=new Innerclass();
在OuterClass外部,创建静态类InnerClass对象的代码如下;
OuterClass.InnerClass obj=new OuterClass.InnerClass();
成员类(member class)
定义一个成员类和定义一个一般的类没有任何区别
class OuterClass
{
class MemberClass
{
}
}
只有创建了类OuterClass对象之后,才能创建MemberClass类
局部类(local class)
局部类和局部变量一样,是指在方法内部定义的类,局部类的定义和一般类的定义类似。
例如:
class OuterClass
{
void method( ) //类OuterClass的成员方法
{
class LocalClass //成员方法中定义局部类LocalClass
{
}
}
}
局部变量定义仅在方法内部使用,方法执行完毕后,其就会消失,同样,局部类也是在方法内部才可以创建对象,一旦方法执行完毕,其就会消失。
类的其他修饰符:final static this super
final修饰符
.final 可用于修饰类,成员变量,成员方法
1.final修饰类
如果类在定义时,加上了final修饰符,说明该类是最终类,不能被作为父类进行继承,
例如:
final class FinalClassDmo
{
}
2.final修饰变量
final修饰的变量是最终变量,即常量,java中的常量可以被访问,但不能被修改其值,如下:
final type variableName=initValue;
final int max=20;
3.final 修饰方法
用final修饰的方法称为最终方法,继承包含最终方法的类的子类不能覆盖该最终方法,即子类不能对父类中的最终方法进行修改
final returnType methodName ()
final int method()
{
}
static修饰符
static修饰符用来修饰类中的变量和方法,用static修饰的成员变量称为静态变量或类变量,用static修饰的成员方法称为静态方法或类方法。
1.static修饰变量
static修饰的变量称为类变量,不用static修饰的变量称为实例变量
类变量在类被加载到内存中时,就被分配内存空间,而实例变量只有在生成类对象时,才分配内存空间
class StaticDmeo
{
static int a; 定义一个类变量、
int b;
public static void main(String args[])
{
生成两个StaticDemo对象
StaticDemo obj1=new StaticDemo();
StaticDemo obj2=new StaticDemo();
obj1.a=10;
obj1.b=20;
obj2.a=15;
obj2.b=25;
System.out.println("对象obj1中变量a的值为" +obj.1a);
System.out.println("对象obj1中变量b的值为" +obj1.b);
System.out.println("对象obj2中变量a的值为" +obj2.a);
System.out.println("对象obj2中变量a的值为" +obj2.b);
结果为:
15
20
15
25
从结果中可以看出不同对象的静态变量a共享同一块内存空间,因此其值相等,而实例变量b,不同的对象有不同的内存空间
2.static修饰方法
在类中使用static修饰的方法称为类方法,而不被static修饰的方法称为实例方法,类方法在类被加载到内存中时,就被分配到内存空间,而实例方法只有在生成类对象时,才分配内存空间
类方法中不允许使用类中的实例变量,只能使用类中的类变量,而实例方法既可以使用类变量,也可以使用类中的实例变量。
this关键字
this关键字指对象自身的引用,即类本身。
super关键字
super关键字指明了是对父类的引用,当一个子类中的变量和方法同父类的成员变量和方法完全相同时,则父类中的成员变量和方法将被隐藏,不能被子类继承,如果想在子类中使用被其覆盖的父类的成员变量和方法时,就可以使用关键字super.
集合工具类 (collections )
所有的集合工具类都只能存放对象而不能存放基本数据类型,java5.0以后支持自动装箱,可以把基本数据类型自动封装成相关对象
常用的集合工具类的关系图
1.Collection与Map的区别是Collection中存放对象时时一个一个的放置,而Map时一对一对的放置
2.List与Set的区别是:List存放的对象是有位置顺序的,而set没有。由于List中的对象有位置差异,因此允许有重复,Set中不允许有重复,set中存放的元素是无序的
3.ArrayList与Vector的主要区别是ArrayList不是线程安全的,如果不加特别处理,多个线程使用同一个ArrayList会出现差错,而Vector不会,Vector是线程安全的
4.HashMap与Hashtable的主要区别是HashMap不是线程安全的,而Hashtable是线程安全的
两个通用Set实现是HashSet 和TreeSet。要决定用哪一个,那是非常简单明了的。 HashSet 要快得多 (对大多数操作是常数时间之于对数时间(constant time vs. log time)), 但不提供排序保证。如果你需要使用 SortedSet 中的操作,或者按顺序迭代对你来说是重要的,那么请使用 TreeSet。 否则,使用 HashSet。 在大多数时间都不使用 HashSet
关于 HashSet,有一件事应该牢记,即就条目数和容量之和来讲,迭代是线性的。因此,如果迭代性能很重要,那就应该慎重选择一个适当的初始容量。容量选得太大,既浪费空间,也浪费时间。 默认的初试容量是101, 一般来讲,它比你所需要的要多。可以使用 int 构造函数来指定初始容量。要分配 HashSet 的初始容量为17:
Set s= new HashSet(17);
HashSets 另有一个称作 装载因数(load factor) 的"调整参数(tuning parameter)" 。如果你非常在乎你的 HashSet 的空间的使用,请阅读 HashSet 文本以获取详细信息。否则,就使用默认值吧。如果你接受默认装载因数,但你确实又想指定初始容量,那么,选一个大约是你期望你的 Set 将增长到的容量的两倍的数。如果你的猜测不着边,它也可以增长,或只是浪费一点空间。但都没有大问题。如果你知道有关正确尺寸的一个最佳值,用它吧;如果不知道,那就使用一个旧的值,或使用一个偶数值。它真的不是非常重要。这些事情只能使 HashSet 稍稍变好一点点。
TreeSet 没有调整参数。除 clone 之外,HashSet 和 TreeSet 都仅有那些由它们各自的接口所要求的操作 (Set 和 TreeSet),而没有任何别的操作。
源文档 <http://topic.csdn.net/t/20040402/15/2918089.html>
向量表 (ArrayList)
向量表实现接口List,因此里面存放的是彼此独立的元素,这些元素在ArrayList里按位置存放,通过位置可以索引出该位置的元素
与数组不同,ArrayList没有容量的限制,ArrayList默认的容量为10,当容量用尽的时候,ArrayList会自动扩大容量,ArrayList自动以50%的容量速度扩展。
游标 (Iterator)
游标提供了遍历集合类的另一种方式,不必关心ArrayList,还是Vector或Set,只要支持游标操作,就通过游标遍历该集合类
List list=new ArrayList(2);
list.add("IBM');
list.add("microsoft");
for(Iterator it=list.iterator();it.hasNext();)
{
Object obj=it.next();
System.out.print(obj);
}
向量(Vector)
向量是另一种形式的列表,vector相对于ArrayList最重要的特征就是Vector是线程安全的
Vector的容量也是自增的,当容量用完的时候,Vector以100%容量的速度递增
哈希集合(HashSet)
存放的元素是无序的,特性与Set一样,之所以叫哈希,是因为使用哈希算法来快速存取元素的
实现了set接口
哈希映射(HashMap)
实现了Map接口
哈希表(Hashtable)
哈希表也是一种Map,与哈希映射相比最大的特点是它是线程安全的,Hashtable可以直接用在多线程里面而不会出错,也是使用的哈希算法,由于内部加入了线程同步机制,因此Hashtable的速度要比HashMap稍微慢些,另外,Hashtable中key与value都不允许为null值,而HashMap允许
异常
java提供了处理此类异常的接口:Throwbale
所有的异常情况被封装成了Throwable类或者该类的子类,所有的异常类型都是Throwable的子类
Throwable有两个直接的子类:
1.一个是Exception,是用户程序能够捕捉的异常情况,可通过继承Excption或其子类来创建自己的异常
2.Error,它定义了那些通常无法捕捉到的异常,一般来说,Error子类通常会导致灾难性的失败
错误类由Error作为顶层,Error定义了在通常环境下不希望被程序捕获的异常,Error类型的异常用于java运行时系统来显示与运行时系统本身有关的错误,如堆栈错误
Exception又分为两种:
1.RuntimeException 是不需要检查的异常,这些异常在编译过程中是不需要检查的,也不需要添加到任何方法的 throws列表中,比如NullPointerException
2.普通的Exception 需要检查的异常
捕捉异常
try
{
}
catch()
{
}
finally{
}
catch(),finally都是可有可无得,但是catch和finally必须至少有一个存在。
为什么有的方法需要捕捉异常,而有的方法不需要捕捉异常
原因在于,那些需要捕捉异常的方法都抛出了一个需要检查的异常
方法名后面用throws声明了该方法可能会抛出的需要检查的异常,如果可能会抛出多个异常,则用逗号隔开
private synchronized void readObject (java.io.ObjectInputStream s) throws IOException,ClassNotFoundException{ }
当调用一个使用throws异常的方法,比如上面的readObject时,编译器会要求写一个try…catch来捕捉这个异常,或者把调用这些方法的那个方法也用throws声明为可能抛出同样的异常
知道了为什么有些方法需要捕捉异常的原理了,就可以使自己的方法也抛出一个异常,让调用该方法的人去捕捉,只需要在方法声明后加一个throws,然后跟着一个或者多个异常类的名称就可以了。然而只是这样做是不行的,这样只是声明了可能会抛出异常,让调用该方法的人留意,但是这个异常是永远不会抛出去的
然后就在方法内部检查条件,如果不符合程序继续运行的条件,就会抛出一个一出来来,方法是用throw关键字后面跟一个异常对象,
例如:检查文件的不存在
if (!file.exists())
{
throw new IOException ("文件不存在");
}
throws与throw区别
方法名后面声明被抛出的异常类列表用的是throws关键字,而方法内部抛出异常对象用的是throw关键字
public Test() throws RepletException {
try {
System.out.println("Test this Project!")
}
catch (Exception e) {
throw new Exception(e.toString());
}
}
throws是用来声明一个方法或类可能抛出的所有异常信息
throw则是指抛出的一个具体的异常类型,用在方法的内部。
通常在一个方法(类)的声明处通过throws声明方法(类)可能抛出的异常信息,而在方法(类)内部通过throw声明一个具体的异常信息。
throws通常不用显示的捕获异常,可由系统自动将所有捕获的异常信息抛给上级方法;
throw则需要用户自己捕获相关的异常,而后在对其进行相关包装,最后在将包装后的异常信息抛出
自定义异常类型
可以根据需求确定自定义的异常为需要检查的异常还是不需要检查的异常,如果需要检查,则可以继承Exception,如果不需要检查,则可以继承RuntimeException。
java语言中进行文件读写是采用流的方式,另外,计算机与计算机与显示器,打印机等I/O设备进行的I/O交互也是采用流的方式
File可以代表文件也可以代表文件夹,它主要用来获取文件的一些信息,比如文件的位置,是文件还是文件夹,存在与否,大小,最后修改的时间等。该类不可以打开任何文件,也不提供任何处理文件内容的功能
注意:构造一个File对象不等于在硬盘上创建文件,仅仅创建File对象操作不对硬盘文件系统有任何影响。
FilenameFilter用来过滤一下不需要的文件,例如过滤掉.txt文件等。
文件的创建
使用File.createNewFile()方法创建文件,创建成功后返回true,创建失败则返回false
创建文件的时候,该文件或文件夹的父文件夹必须存在,否则会因路径找不到而抛出IOException异常
文件夹的创建 File.mkdir(),创建成功则返回false
文件的删除和更名
文件的删除和文件夹的删除都使用File.delete(),删除成功返回true
文件的更名File.renameTo(File dest)方法
File类只能对文件进行一些简单的操作,比如取属性,创建删除等,并不支持文件内容的读写,要想对文件进行读写操作,就必须通过Stream来完成
流(Stream)
流是传递数据信息的载体
输入流是将数据从数据源传递给程序,而输出流则是将数据从程序送到期望的地方,比如显示器,文件等
最初设计的输入输出类是面向字节流的,即支持8位的字节流,分别由派生抽象类InputStream和OutputStream
InputStream,OutputStream及其子类都是面向字节的,对中文的支持较差,容易出现乱码
Reader,Writer使用的是Unicode编码方式对中文有很好的支持,不会出现乱码情况
一般来说 Sytem.in用来接收用户在标准I/O设备上的输入(一般是键盘),System.out.用来将内容输出到标准I/O设备上,如显示器
读取文件的操作
读取文件的操作有两种办法:
一种是基于字节流的InputStream,另一种是使用基于Unicode字符的Reader,InputStream一般用在读取二进制文件,比如应用程序,图片文件,媒体文件等。Reader一般用于读取文本文件,比如txt文件,Log文件等。
文件的锁定操作
使用FileLock类锁定文件,
随机访问文件类(RandomAccessFile)
文件的随机访问主要通过类RandomAccessFile来完成,它使用seek()方法从文件中的一个记录移动到下一条记录,进行读或者写,而不需要知道总共有多少个记录,它不需要把所有的记录全部加入到内存再进行读写操作,因此对访问大文件来说,这是一种资源花费少的,执行效率高的选择。
java还可以用于文件的压缩,解压等
Java的高级特性
从java5.0开始Java开始支持自动装箱(auto boxing)和拆箱(unboxing),这样使得程序开发者可以直接把int当Integer使用,或者把Integer当int使用,无需手工转换
自动装箱:把基本数据类型封装成类对象
拆箱:把类对象拆成基本数据类型
Int i=new Integer(4);
Integer j=4;
Java5.0编译器会判断等号两边的数据类型,如果左边是基本数据类型,而右边是对应的类,则类会使用形如intValue()的方法取得其基本数据类型值,如果左边是对应的类,而右边是基本数据类型,则基本数据类型会使用形如valueOf()的方法取得其对应的类对象
For/in遍历数组和集合
1.遍历数组:
例子:
String array[]={"a","b","c","d");
for (String s:array) //在for循环的括号里声明一个字符串变量,冒号表示遍历数组的所有元素,把循环当前的变量值付给 S tring类型变量s
{
System.out.println(s);
}
2.遍历集合(集合中存放的都是对象,是不能存放基本数据类型的)
public class TestFor {
public static void main(String args[]){
List list=new ArrayList();
list.add("string");
list.add("integer");
for(Object obj:list){
System.out.println(obj);
}
}
}
上面的代码只能先取到了Object类,如果List里面是String类型的数据,还得写代码String s=(String)obj进行强制转换,还可以有种更优雅的遍历方式,即范型
List <String >list =new ArrayList<String>();
list.add("string");
list.add("integer");
for(String obj:list)
{
System.out.println(obj);
}
可变参数方法
从java5.0开始支持,可变参数的方法,例如Sytem.out.printf()方法,String类的format()方法等
可变长方法的定义:
例如:formate方法
public static String format(String 。。。Args)//是三个点
定义一个可变长参数方法是在参数类型的后面加上省略号,然后加上可变长参数名,可变长参数在方法的内部变现为数组,可以使用传统的数组遍历方式来使用数组,也可以使用新特性for/in循环形式。
public static double avg(double...values)
{
double total=0;
int count=values.length;
for(double i:values)
{
total+=i;
}
return total/count;
}
协变式放回类型
协变式放回类型(covariant return types)允许在覆盖父类方法的时候,是父类方法的返回值更加具体
例如:ArrayList类的get(int index)方法返回的是Object,继承ArrayList之后即可以覆盖get方法,并修改返回值为String,因为String也是Objectde 一个子类,在java5.0之前这是不允许的
静态导入
Java5.0以后的版本支持使用静态导入(import static)导入某个类的静态方法和静态变量,在使用的时候不需要再指名类名,直接应用变量名或者方法即可,import static为新增的一个指令
例如:
import static java.lang.Math.PI;
import static java.lang.Math.sin;
范型(Generic)
类与方法都可以被泛型话,类泛型由类名后面跟上一个或多个由三角括号包含的类型变量组成;方法泛型主要体现在返回类型与方法内部
例如:
ArrayList类的泛型与方法泛型
public class ArrayList<E> extends AbstractList<E> implements List<E>,RandomAccess,Cloneable,java.io.Serializable
{
…
public E get(int index)
{
…
}
}
类泛型ArrayList<E>代表的意思是ArrayList类里存放的数据类型只能是E类型及其子类,如果不是,编译会出错
方法泛型 public E get(int index)
代表的意思是该方法返回的类型是E类型,使用的时候可以直接当做E类型使用,而不用从Object强制转换为E类型
E可以任何类型
定义一个只存放String数据类型的ArrayList
List<String> list=new ArrayList<String>();
list.add("string1");
list.add(string2");
使用多个泛型
有时容器中需要放置多个对象,比如Map中,必须是key和value两个对象成对存在的,而且这两个Object的类型还可能不一致,这时就需要使用泛型来约束
Map<String,Date> map=new HashMap<String,Date>
泛型通配符
由于通配符的不确定性,通配符只能用来进行类型安全检查,而不能用来声明具体的类泛型
List <?> list 表示List放置任何类型,不过单独使用“?”没什么用,问好一般与extends和super使用
?与extends连用表示指定类型及其所有子类
?与super连用表示指定类型及其指定类型的父类
例如:
public static void numberList (List <? Extends Number> list)
public static void deteList (List <? Super Date> list>
枚举类型 enum
枚举类型不能声明在方法的内部,而只能声明为类变量
Public enum Sex {male,pemale,unknown,};
枚举类型里的变量是实实在在的对象,可以把male,pemal,unknown看作是一种内部匿名类对象,并且它们是public(可以在Sex外部引用),static(可以由类名Sex直接引用),final(引用不修改)
ublic class Enum {
public enum Sex{male,female,unknow};
public static enum type{charman,person};
public static void main(String args[]){
System.out.println(Sex.female);
System.out.println(type.charman);
}
}
扩展枚举类型
enum同Interface,class一样是一种对象,因此它可以扩展,添加属性或者方法
enum的限制:
enum内部可以由构造方法,但不能有public的构造方法
enum内置对象间必须使用逗号隔开,声明完所有的内置对象之后用分号结束
enum内置对象必须使用声明的构造函数,否则编译错误
static enum Type {
MANAGER("经理",10000);
ASSISTANT("助理",6000); //给各枚举对象添加属性
WORKER("员工",4000);
private String name;
private double pay;
Type(String name,double pay) {
this.name=name;
this.pay=pay;
}
}
注解 (annotation)
注解是以@开头的一种标记,用来修饰包,接口,类,属性,方法和变量等。包含在注解里的信息以key=value的属性对的形式提供给程序元素
@Column(name="clumen_name")