可变参数:
public static 返回值类型 数组名称(数据类型 ... 参数名称){}
匿名对象:
匿名对象就是只使用一次的对象
new Person.SayHello();
String类
String的两种实例化方式:
String本身就是一个类,在String类定义了如下的方法
可以直接赋值,可以使用构造函数赋值
String str2="Hello";
String str1=new String("Hello");
对于"=="操作符,比较的是两个对象的地址是否相等
使用String中的equals()方法比较的是字符串的内容
*一个字符串实际上就是String的匿名对象
一个字符串就是用""括起来的,那么字符串的常量实际上九属于String的匿名对象
字符串的内容一旦申明之后则无法修改
String类的常用方法:
字符与字符串
在各个语言中实际上一个字符串表示的是一组字符
字符串的其他操作
去掉左右空格:trim()
取得字符串的长度length()//方法就要有括号
深入引用(重点)
划分堆和栈的内存分配空间
this关键字(重点)
1.操作属性
2。操作构造方法:消除重复代码。this()要放在语句的第一行
3。在使用this调用构造函数的时候至少有一个构造方法是没有使用this()调用的,而此构造方法将作为调用的出口,一般这个出口都会使用无参构造完成
最重要的概念:this表示当前对象
主方法的含义
public static void main(String args[]){}
main是系统内建的方法名称
程序的内存划分:
1、栈内存
2、堆内存
3、全局代码区:保存所有的操作方法
4、全局数据区:保存所有的static属性
系统退出:
System.exit(1)//只需要设置了一个非零的数字
程序设计的思路:
。完成基本功能
。改善功能,加入一些验证
。形成更好的结构,加入一些类的设计
。主方法中不能编写过多的代码
对象数组:
构造方法私有化
单例设计:
此程序的意义在于,如果现在一个类只能有一个实例化对象的话,那么这样的设计就被称为单例设计
当整个系统中只需要一个实例化对象就可以使用单例设计这种设计模式
**static的一些相关应用
使用static可以统计一个类产生了多少个实例化对象
因为static的属性是所有对象共享的
static方法只能调用static属性方法,而不能使用非static书慈宁宫方法
***代码块
1、普通代码块(直接在一个方法中出现的“{}”就成为普通代码块)
2、构造快(使不使用无所谓,优先于构造方法)
3、静态快(静态块优先于构造块,并且只执行一次)
4、同步代码块
****内部类(重点)
定义:在一个类的内部还有一个类
缺点:程序的结构混乱
唯一优点:在于方便的访问外部类的私有成员
一个内部类如果使用static
内部类可以在任意的地方使用,比如在方法中定义内部类
在方法中定义的内部类,可以直接访问外部类中的各个成员,但是要访问方法中的参数,则要在参数上使用final关键字声明床底在java中$代表.
***链表的应用
单向链表:巩固引用传递
****面向对象的三大特征;封转、继承、多态
**继承的基本概念:
继承就是扩张已有类的功能,在继承中分为子类和父类,父类有时候又称为超类(super class)
子类有时候也被称为派生类
**继承的限制
在使用继承的时候虽然可以扩充类的功能,但是本身也是存在以下限制的:
在java中不允许多重继承:一个子类只能继承一耳光父类,不能继承多个父类
在java中允许多层继承
在java中子类不能访问父类私有操作,而只能继承全部公共操作
****子类实例化的过程
构造方法的主要目的:是为类中的属性初始化
在实例化子类的对象的时候肯定要首先实例化父类中的内容,为父类初始化
父类在程序中又被称为super class
子类对象实例化之前肯定会先调用父类的构造方法
*****方法的覆写(重点)
子类定义了与父类同名的方法,称为方法的覆写
在方法覆写的时候一定要注意访问权限问题,被覆写的方法不能拥有比子类更严格的访问权限
*只要是使用子类实例化对象,调用的方法也被子类覆写过的话,则永远调用的是覆写过的操作
记住;永远不是覆写,而是重新定义
如果想调用父类中被子类覆写过的方法,则只能通过super方法()的形式调用
还可以进行属性的覆写和方法的覆写,其中属性的覆写用到并不怎么多,因为属性多为private,不能被覆写,所以只需了解即可
*****两个重要比较(重点)
、方法重载与覆写的区别
、this与super的区别(具体区别去MLDN16中的文档查找)
*****final关键字(重点)
可以申明类,申明的类不能有子类
申明方法,申明的方法不能被子类覆写
申明变量,申明的变量就成为了常量,常量不能被修改
在java中如果使用final声明一个常量的话,则常量的标识符必须全部大写
在final中冶存在一个很重要的概念:全局变量,使用public static final申明的产量成为全局常量
****抽象类(重点)
使用abstract关键字声明抽象类和抽象方法
实际上讲,抽象类就是比普通类多了一个抽象方法而已
抽象类的属性如果想要初始化,则肯定还是需要依赖与构造方法
****接口(重点)
接口是一个特殊的类,在java中接口是由抽象方法和全局常量组成的
接口与抽象类一样,需要有子类,那么子类此时不在称为继承类,而是实现接口,通过implements关键字完成
既然接口定义上已经明确的要求是由抽象方法和全局常量组成,那么在接口定义的时候就可以简化操作
比如可以将public static final INFO="CHINA";
简化成 String INFO="CHINA";
一个类虽然只能继承一个父类,但是可以实现多个接口,使用接口完成多继承的能力
接口也可以同时继承多个接口
一个抽象类可以实现多个接口,但是一个接口不能继承一个抽象类
****对象的多态性(最重要的部分)
多态性可以让程序变得更加灵活
方法重载和方法重写实际上就属于多态性的一种体现
真正的多态性中还包含了了一种称为对象多态性的概念
对象的多态性主要是指:子类和父类对象的相互转换关系
、向上转型:父类 父类对象=子类实例 --》自动完成
、向下转型:子类 子类对象=(子类)父类实例 --》强制完成
如果想要进行向下转型,则首先必须产生向上转型的关系
*****instanceeof关键字
判断该对象是否为这个类
对象instanceeof类-->返回boolean类型的数据,值就是true或false
在保证对象的向下转型操作正确,在操作前最好加上instanceeof关键字进行判断。
****在继承关系中,父类的设计非常重要,,只要父类的设计合理了,则代码开发就非常的简便
*****抽象类的应用
从对象多态性的概念上来看,子类为父类实例化是一个比较容易的操作,因为可以发生自动的向上转型关系,那么调用的方法永远是子类覆写的过程
那么此时就可以利用次概念通过对象多态性为抽象类实例化
抽象类的本身最大的用处在于模板设计
****接口的应用
接口也可以像抽象类那样通过对象多态性进行对象的实例化操作
接口实际上是作为一个标准存在的
******图像问题
使用powerDesigner软件建类图
******接口和抽象类
**适配器设计模式
正常情况下一个接口的子类要实现全部的抽象方法
想要值实现接口中的部分方法,那么先用一个类将接口实现了,但是所有的方法都属于空实现,之后再继承此类,实现接口的这个类应该用抽象类,因为抽象类不能被直接使用
**工厂设计模式
强调;主方法实际上就是一个客户端,客户端的代码越简单越好
所有的实例化对象都是通过工厂类取得的。那么客户端调用的时候根据传入的名称不同,完成的功能也不同。
将字符串的写在前面,通过字符串的匿名对象调用方法,则不会出现空值异常
String str=null;
"Hello".equals(str);
**代理设计模式
设计一个代理类,实现需要代理类的功能,并且还有自己更过的功能
*******抽象类与接口的区别(绝对重点)
见MLDN24文档比较表格
抽象类的设计模式:模板设计
接口的设计模式:工厂设计、代理设计
如果抽象类和接口同时都可以使用的话,优先使用接口,因为接口避免单继承的局限
一个抽象类中允许包含一个接口
abstract class A{
public abstract void fun();
interface B{//内部接口
public void print();
}
}
一个接口中也可以一个抽象类
*****object类
在java中一切都是继承关系,那么既然一切都是继承关系,默认情况下就是继承自object类
任何对象都可以使用object进行接收
object类的主要功能不止于此,对于一个完整的类来讲,应该覆写object类的一下三个方法:
toString():对象打印调用
equals():对象比较调用
hashcode()
Object可以接收任意类型的对象引用
*****开发中的一个原则:一个类永远不要去继承一个实现好的类,要么继承抽象类,要么实现接口,其中以接口为优先使用。可以避免单继承的局限
*****匿名内部类
内部类:在一个类的内部还有另外一个类,称为内部类
匿名内部类是在抽象类和接口的基础上发展起来的
使用匿名内部类使用较少,有两种情况下可以经常看见匿名对象类的使用;
、java的图形界面
、Spring开发框架
*****包装类
在java中提倡一种概念:一切皆对象
在包装类的操作中存在装箱及拆箱的操作
、装箱操作:将基本数据类型变为包装类称为装箱操作
、拆箱操作:将包装类变为基本数据类型称为拆箱操作
在JDK1.5之后增加了很多新特性,例如:foreach、可变参数、自动装箱及拆箱操作
实际上可以通过包装类取得最大值和最小值
在装箱之后,通过MAX_VALUE取得最大值,而且是常量
对于包装类来讲,自动装箱金额拆箱功能是一个重要的特点,但是还有一个重要的特点:
、可以将字符串变为基本数据类型
利用parseInt、parseFloat方法
需要注意的是,字符串必须由数字组成,如果有非数字存在,则会出现代码错误
*****异常的捕获及处理
所谓的异常处理,就是指程序出现问题时依然可以正确的执行完
try{
可能出现异常的语句
}
catch(异常类 异常对象){
异常处理
}
catch(异常类 异常对象){
异常处理
}
finally{
异常的出口
}
在异常捕获的时候,有一个注意,捕获更细的异常要放在捕获更粗的异常之前的
对于实际开发来讲,如果要处理异常的话,则最好分开处理
****throws关键字
在程序的方法声明处可以使用throws关键字,使用此关键字的最大好处:在方法中不处理任何的异常。而交给被调用处处理
如果在主方法处使用了throws关键字的话,则所有的异常交给最大的头:JVM进行处理了
*******throw关键字
在程序中可以使用throw关键字人为的抛出一个异常
在异常的处理中,实际上每次产生异常的时候都是产生了一个异常的实例化对象。那么此时,也可以通过抛出异常对象的方式完成
****异常的标准格式
在方法中利用try..catch代码块在catch中抛出异常
try{}
catch(exception e){
throw e;
}
在主方法中冶利用try..catch代码块,打印异常
try{}
catch(exception e){
System.out.print(e);
}
*****异常的其他处理
只要是RuntimeException的异常对象,虽然使用了throws关键字,但是在程序中也可以不使用try..catch进行处理
*******assert关键字
这个关键字表示断言
就是表示说,当程序执行到某条语句的之后,其结果肯定是固定的值
但是,从实际的角度上来讲,断言的使用很少,所以只做了解
*****包的定义
包的实际上就是一个文件夹,在不同的文件夹中可以有同名的类,那么这就是包的作用通过一下的命令进行大包编译
javac -d . Hello.java
-d表示生成的目录,根据package的定义生成
.表示在当前所在的文件夹
****导入包
用import关键字
如果要导入一个包中的很多类,那么可以使用包名.*来导入所有类
*****静态导入
import 包路径.静态类.*
这样就可以直接使用静态类下面的方法了
java.lang.reflect:此包为反射机制包,是整个java乃至这个java世界中最重要的包,此包可以完成大量的底层操作
java.util包:工具包,如果把此包掌握的非常清楚,则可以方便的做各种设计,各种开发
java.io IO操作
******访问权限
public(最大,公共的,共同访问) defaul(默认的,只能在本报中访问)、private(最小,只能在本类中访问)
protected(在本包,以及不同包的子类中可以访问)
*****命名规范
在java中所有的属性、类都是有命名规范的,开发时必须严格的按照命名规范的要求去开发代码
1、类的命名:每个单词首字母大写
方法的命名:第一个单词的首字母小写,之后的每2、个单词的首字母大写
3属性的命名:第一个单词的首字母小写,之后的每2、个单词的首字母大写
4、常量的命名:所有的单词字母大写
5、包的命名:所有的单词字母小写
*****jar命令
在开发中,一个系统会有很多的类出现,如果现在直接吧这些类散装着给对方,则肯定不好,所以会有将这些类打成一个jar包,以jar包的形式把这些类交给用户使用。
在java中使用jar命令
如果想使用jar包,一定要配置classpath
所有的类必须方法一个包中,没有包的类是不存在的
******JDT的使用
是java的开发开发环境
快捷键 ctrl+Shift+F 格式化
代码调试
只需要设置好断点即可
*****Junit的使用
在测试的理论,分为白盒测试和黑盒测试
黑盒测试:是测试功能的
白盒测试;是测试性能的
选择Junit新建testclass
*******CVS的使用
从日常的开发中,基本上都是多个用户对同一台服务器上进行开发的提交
所以为了更好的管理服务器上的代码,那么提供了一种工具为版本的控制工具,最早是CVS,那么最新流行的的SVN,只能在LinUx下使用
*******泛型的产生
因为程序中可以接收三种数据类型的数据,所以为了保证程序的正确性,最好使用Object完成,因为Object可以接收 任意的引用数据类型
泛型,此技术最大的特点是类中的属性都可以由外部决定,而且在声明类的时候都应该采用以下的形式
class 类名称<泛型类型,泛型类型...>{
}
由外部决定数据类型
加入泛型之后,可以对程序的操作起到更加安全的目的
******3.3泛型的其他注意点
在使用泛型的时候,实际上有很多很小的注意点,例如:构造方法上依然可以使用泛型或者有一种称为泛型的擦除
设置内容都有外部所决定
*****擦除泛型
在使用的时候没有指定泛型类型的话,则表示擦除该泛型
泛型一旦擦除之后,将按照Object的类型进行接收,以保证程序不会出现任何错误
在一般的开发中,不要擦除泛型
******泛型中的通配符
在泛型的操作中通配符使用较多
程序中的?表示的是可以接收的任意的泛型类型,但只能是接收输出,不能够修改
*****泛型的上限
上限就是指一个的操作泛型最大的操作父类
泛型的上限通过" ? extendds 类"
这种泛型的上限也可以在方法中使用
****泛型的下限
指的是只能设置其具体的类或者父类,设置的语法如下
"? super 类"
******泛型接口
泛型也可以在接口中使用
interface 接口名称<泛型类型,泛型类型..>
{}
*****泛型方法
泛型可以在方法上定义,而且在方法上使用泛型,他的类不一定是一个泛型类
public <T> print(T 参数名){//定义泛型方法
}
泛型数组
public <T> T[] print(T ... 参数名){//定义泛型数组
return 参数名;
}
*****泛型的嵌套设计
泛型的嵌套
<Object<String>>
泛型的可以在接口上设置,值顶泛型接口的子类需要明确给出类型
使用接口进行解耦合操作,所有类之间的关联用接口完成
******掌握多线程的两种实现手段
*****进程与线程
在计算机操作系统的发展来看,经历了这样的两个阶段
、单进程处理:在同一个时间段上只能有一个程序在执行
、多进程处理:在用一个事件段上会有对个程序运行,但是在同一个时间点只能有一个车程序执行
线程是在进程基础上的进一步划分,如果进程消失了,那么线程就消失了,反之,进程未必会消失
java本身就是属于多线程的语言,所以提供了线程的处理机制
*****线程实现的两种机制
在java中可以有两种实现多线程的操作,一种是继承Tread类,另外一种是实现Runnable接口
****Thread类
是在java.lang包中
继承Thread类,重写run方法
使用start方法起动线程
想要调用线程,在java中定义了native关键字,使用此关键字表示可以调用操作系统的底层函数,那么晚这样的技术又称为JNI技术(Java Native Interface)
而且,此方法在执行的时候将调用run()方法完成,有系统默认调用
*******Runnable接口
在实际开发中,很少使用继承Thread类完成多线程操作,而是通过Runnable接口来实现多线程的操作
此接口只定义了一个run()方法,所以只需将其覆写即可
在Thread类中存在一个构造方法,该构造方法接收Runnable的子类实例,也就是说可以通过Thread类来启动Runnable实现的多线程
******两种实现方法的区别及联系
在程序的开发中只要是多线程则肯定永以实现Runnable接口为正统操作,因为实现Runnable接口相比继承Thread类有如下的好处
1、避免单继承的局限,一个类可以同时继承实现多个接口
2、适合资源的共享(重要),资源共享
实际上Thread类和Runnable接口还是有联系的
发现Thread类也有实现Runnable接口
使用了代理设计模式
*******同步与死锁(理解)
所谓的同步就是指多个操作在同一个事件端内只能有一个线程进行,其他操作线程就要等待此线程操作完毕
**同步代码块
使用synchronized关键字,
synchronized(this){}同步代码块
也可以使用此关键字增加同步方法
public synchronized void 方法名(){}
发现同步可以保证资源的完整性,但是过多的同步也会出现问题
java中方法定义的完整格式
除了之前掌握的一些关键字,还增加了两个,一个是同步关键字和表示操作系统的底层函数的native关键字
访问权限 关键字 返回值数据类型 方法名(参数名){
//方法体
}
程序中使用过多的同步,就有可能出现死锁的情况
概念:
多个线程共享同一资源的时候需要进行同步,但是过多的同步会造成死锁
*****生产者和消费者(理解)
生产者不断产生,消费者不断取走生产者生产的产品
*****Object类对线程的
唤醒操作,notify()方法 nptifyall()
唤醒操作是将休眠中的线程立即执行
******StringBuffer
String是一个字符串,但是字符串的内容不可改变,改变的是内存地址的志向,那么如果现在想要让字符串的内容可以修改,则必须使用StringBuffer类完成
*****StringBuffer的基本使用
使用Append来增加字符串的长度
在使用StringBuffer是不能像String那样可以直接使用字符串进赋值操作,一定要使用关键字new来开辟控件,然后再append来给字符串赋值
在程序中将+号替换成append方法,String和Stringbuffer之间没有直接的关系,如果想要将Stringbuffer变成String要用toString方法
那么一般情况下Stringbuffer往往都用在频繁修改字符串的时候
在Stringbuffer中提供了大量的操作方法
在指定位置处添加内容,
、insert方法,
、默认的情况下所有的内容都在原有的字符串的后面添加
删除指定范围的内容,delete方法,delete(start,end)
反转字符串的内容,使用reverse方法
******runtime类
每一个JVm启动的时候都会产生一个runtime实例
但是此类的构造方法被私有化,则此类的返回值是一个runtime的实例
实际上可以通过runtime类直接运行本机的程序
Runtime.getRuntime().exec(想要运行的程序名称);
Proces 类 操作进程
Process.destroy销毁当前进程
********Runtime查看当前系统信息
通过maxMemory().freeMemory().totalMemory()
查看系统内存信息
Runtime有一个gc方法,垃圾回收方法
**********System类
System类时一个系统类,是一个陪伴我们时间最长的类:例如System.out.println()
****取当前时间
使用此类可以取得计算的时间,
System.currentTimeMillis()方法
***System与垃圾收集
System.gc()方法,调用此方法实际上就是调用Runtime中的gc方法
如果一个对象不用的话则就有可能进行垃圾的收集,但是如果一个对象在被收集之前需要做一些收尾工作
在被回收之前会先调用finalize方法,此方法在Object类中
******国际化程序实现(理解)
国际化程序,一套程序可以同时适应多个国家人的语言要求,那么这样的程序称为国际化程序
如果想要实现国际化程序,则必须依靠Locale、ResourceBondle、MessageFormat几个完成,并结合属性文件
每个国家都有自己的编码
创建Local类的对象有两种方式
、取得本机的语言、直接用java.util中的Local类,利用getDefault方法实例化
、是直接指定一种现实的语言、public Local(String language,String conutyr)
但是如果想要实现国际化只靠Local是不够的,还要取得属性文件
ResourceBoundle类中的getBondle方法
在JDk中提供可一个转换工具,可以将文字变为16进制编码,此工具在bin\native2ascii.exe
在整个国际化程序中,属性文件是最关键的
动态文本
MessageFormat.format(对象,"格式化字符串")
从实际的角度来看,一般不会使用类表示一个资源文件的内容,都使用properties文件保存
******日期操作类(重点)
在java中对日期的显示进行了很好的类的支持,使用Date、DateFormat、SimpleDate等等
*****Date(重点)
java.util.Date类
此类的使用非常简单
此类是一个非常重要的类,在日后的喝多开发中都必然使用类
new Date() 需要导入java.util.*
*****Calendar类
这个类比较符合国人的喜好,使用时查文档即可
小结:
StringBuffer比String性能更加,而且最大的特点是StringBuffer的内容可以修改而String的内容无法修改
Runtime使用单例设计,需要getRuntime()方法取得Runtime类的实例
利用gc()方法回收垃圾
Object类的finalize()方法用于对象回收时释放空间
使用Calendar类可以将时间精确到毫秒
*****DateFormat
DateFormat与MessageFormat一样都属于Format的子类,此类专门用于格式化使用
在DateFormat中存在一个format方法,他接收Date类型,接收Date型的数据类型转换为String类型
getDateInstance()方法取得一个Date的实例
SimpleDateFormat类(重点)
SimpleDateformat类时DateFormat类的子类,但是其主要功能有两个
、取得指定格式的日期和时间
、进行日期的转化操作
****日期的格式化操作
格式在SimpleDateFormat实例化时指定
转换 利用parse方法转换
******math类和Random类
Math类时操作数学方法的,所有方法都是静态方法
所以可以使用Math.方法名即可,比如Math.PI
Round是四舍五入的方法
*****Random类时随机产生
Random r =new Random();
通过r.nextInt(100)方法可以取得1-100之间的随机数
******NumberFormat类(掌握)
是Format类的子类
在NumberFormat有一个子类为:DecimalFormat类
通过format方法完成格式化
实例化对象,getInstance()方法实例化
因为现在的区域是中国明所以数字的格式化上按每三位“,”的形式出现
*****decimalFormat类
与SimpleDateFormat类相似,也存在一套格式化模板的东西存在
******大数操作(重点)
大数操作指的是数字非常大,达到已经超过了整个数据类型的保存范围
如果在最早碰到大数,都采用字符串的形式进行处理的
java中为了解决这样的难题提供了两个大数字对象:BIgInteger、BIgDecimal
*****BigDecimal
四舍五入操作,利用常量ROUND_HALF_UP,来实现
*********对象克隆(理解)
可以将一个对象完整的复制下来
Object类提供了一下的方法,完成了对象的克隆
public Object clone()
对于克隆操作并不是每一个对象都应该具备的
只有实现了Cloneable接口的类的对象才能被克隆
,此接口没有定义任何方法,只是作为一个标识
*****Arrays类(理解)
利用sort方法进行排序
fill方法进行填充
tostring方法进行输出
*****比较器
如果要想想要数组排序、则所有的元素的必须实现Comparable接口
*****Comparable接口
实际上是一个比较接口,使用了泛型,并且只定义了一个方法compareto,用来进行比较,他的返回值有三种类型,小于-1、大于1、等于0
****早Comparable发现compareto()方法可以返回类型:-1,0,1,实际上此种排序就类似于常见的BT(Binary Tree)排序
二叉树完成后要使用中序遍历的方式完成,左根右
排序之后的数据
任何的数据类型(String Integer),都可以使用Comparable进行接收
既然呀使用排序,那么所有数据都使用Comparable来接收
public Comparable<?> date;
看代码中的实例(在java中使用二叉树)
******另一种比较器:Comparator
Comparable接口在使用的时候直接在类中实现即可,那么如果现在一个已经开发完成了,则肯定不能再去修改,那么此时可以使用Comparator比较器
在开发中明显使用Comparable最为简单,所以使用Comparable最好
********正则表达式
是在Jdk1.4之后加入到java的开发环境中的埋在JDK之前如果想使用正则表达式进行开发,则必须要单独去下载开发包,正则最早从PHP中开始兴起的,只要的作用可以非常方边的完成一些复杂的严整功能等基本实现
“\d+”判断是否为数字
如果要想知道有多少种正则表达式,可以查看文档中的java.util.regex中的Pattem类。
字符类
[abc] a、b 或 c(简单类)
[^abc] 任何字符,除了 a、b 或 c(否定)
[a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围)
[a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](并集)
[a-z&&[def]] d、e 或 f(交集)
[a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](减去)
[a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](减去)
预定义字符类
. 任何字符(与行结束符可能匹配也可能不匹配)
\d 数字:[0-9]
\D 非数字: [^0-9]
\s 空白字符:[ \t\n\x0B\f\r]
\S 非空白字符:[^\s]
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w]
边界匹配器
^ 行的开头
$ 行的结尾
\b 单词边界
\B 非单词边界
\A 输入的开头
\G 上一个匹配的结尾
\Z 输入的结尾,仅用于最后的结束符(如果有的话)
\z 输入的结尾
Greedy 数量词
X? X,一次或一次也没有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,但是不超过 m 次
但是,如果想要使用以上的正则表达式,则需要Pattern类和Matcher类的支持,在Pattern类中需要制定要操作的正则表达式规范,而在Matcher进行验证
******pattern类
Pattern类是一个单例设计,利用compile方法取得Pattern类的实例,并设置正则
还有spilt方法,字符串截取
pattern方法,返回使用的正则表达式
matcher方法,为Matcher类实例化
*****Matcher类的主要功能主要是进行正则的匹配们通过pattern类定义完正则,再使用Matcher类进行验证
******String类对正则的支持
matcher方法,replaceAll方法。Split方法
replaceFirst方法
在开发中基本都使用String类中的功能,因为已经足够强大了
正则可以方便的完成验证的操作,正则表达式是一组标准性的规范,在各个语言中都可以使用,String对正则已经有了很好的支持
****************************
java基础部分必须掌握的四个部分
面向对象,包括各个概念及使用
java类集
java IO
JDBC
******************************
******Java IO
在java IO实际上很好的体现了Java的面向对象的设计思想
IO中主要的类和接口是,File。IputStream、OutStream、Reader、Writer、Serialzable接口
****File类
利用构造方法实例化,如:File file = new File("d:\\demo.txt");
然后利用createNewFile方法创建文件
file.delete() ;// 删除文件
if (file.exists()) {// 如果文件存在
isFile判断是否为文件
isDirectory判断是否是目录
String path[] = file.list(); // 列出全部的内容
file.listFiles(); // 列出全部的子文件或文件夹,如果想要理出全部内容的话,使用后者比较合适
file.getParentFile().mkdir();//创建文件夹
getparentFile方法,找到父的路径
利用常量File.separator确定分隔符,适应各个不同的平台,路径分隔符pathSeparator
所以对于实际的开发来讲,必须使用这样的常量进行声明,这里的常量没有全部大写,这是由于java的历史决定的
*******RandomAccessFile(理解)
RandomAccessFile类的主要功能是随机的读取文件内容,也可以将内容写入文件
如果想实现随机读取的话,则在存储数据的时候要保证数据长度的一致性,否则是无法实现功能的
读模式:r
写模式 :w
读写模式 rw(最重要的方法)
RandomAccessFile raf = new RandomAccessFile(file, "rw");// 以读写的形式进行操作
raf.writeBytes(name); // 以字节的方式将字符串写入
raf.writeInt(age); // 写入整型数据
raf.close();// 文件操作的最后一定要关闭
raf.skipBytes(12);//跨过12位字节
raf.readByte(); // 读取字节
raf.readInt();// 读取数字
在文件中提供了一个指针,完成了具体的操作功能
RandomAccessFile可以方便的进行读写操作,但是操作起来毕竟很麻烦,所以在java中要想进行io的操作一般都使用字节流或字符流完成
******字节流和字符流(重点)
字节输出流OutputStream,字节输入流InputStream
字符从输出流Write
字符输入流是Reader
*****io操作的基本步骤
1、使用file找到一个文件
2、使用字节流或字符流的子类为OutputStream、InputStream、Write、Reader进行实例化操作
3、进行读或写的操作
4、关闭:close(),在流的操作中最终必须进行关闭
*******字节输出流:OutputStream
在java包中OutputStream是字节输出流的最大父类,此类是一个抽象类、所以使用时需要依靠子类进行实例化操作
如果此时需啊哟完成文件的输出操作,则使用FileOutputStream、和OutputStream
write(b); // 写入数据,写入全部字节数组,所以之前要先将字符串类型转换为字符数组
str.getBytes(); // 将String变为byte数组
new FileOutputStream(file, true); // 通过子类实例化,表示追加
这样一来就会在原有的内容后面追加内容
*******字节输入流 InputStream
使用InputStream可以读取输入流的呢urong,那么此类的定义如下
public abstract class InputStream exends Object Implement Closeable
(){},
是一个抽象类,通过FileInputStream进行实例化
new String(b, 0, len); // 输出内容,只输出len的大小
(int)file.length()文件中的大小
input.read(b); // 将内容读入到byte数组中
******字符输出流 :Write
Write类是在IO包中操作字符的最大父类,主要功能是完成字符流的输出,Write的定义格式
属于抽象类,需要用FileWrite进行实例化
使用Write操作的时候不用再转换了,直接String
Writer out = null; // 声明字符输出流
out = new FileWriter(file); // 通过子类实例化
out.write(str); // 写入数据
******字符输入流:Reader
字符输入流和字节输入流不同的地方,使用的是char数组。Reader还是一个抽象类,需要通过FileReader进行实例化
读取的方法:
read
input.read(b); // 将内容读入到byte数组中
******字节流与字符流的区别
以上操作的代码有两组,那么实际中应该使用哪组更好呢?
在执行时如果没有关闭操作,字节流可以查看,字符流不能查看,(一个有内容,一个没有内容)
flush方法表示刷新
得出这样一个结论:字节流在操作的时候是直接与文件本身关联的,不使用缓冲区 字节-->文件
字符流在操作的时候是通过缓冲区文件操作
字符-->缓冲-->文件
在综合来讲,在传输或者在硬盘桑保存的内容都是以字节的形式存在的,所以字节流的操作特别多,但是在操作中文的时候字符流比较好使,因为中文是占连个字节的
字节流是直接实现底层的IO操作
******内存操作流(重点)
在之前的讲解FileInputStream和FileOutputStream的时候所有的操作的目标是文件,那么如果现在假设有一些临时的信息要求通过IO操作的话,那么如果将这些临时的信息保存在文件之中则肯定很不合理,因为操作的最后还是要把文件再删除掉,所以此时在Io在就提供了一个内存的操作流,通过内存操作流
输入和输出的目标是内存
ByteArrayInputStream的构造方法(byte
[] buf)
表示把内容向内存之中写入
ByteArrayOutputStream bos = null; // 内存输出流
ByteArrayInputStream bis = null; // 内存输入流
new ByteArrayInputStream(str.getBytes()); // 将内容保存在内存之中
new ByteArrayOutputStream(); // 内存输出流
while ((temp = bis.read()) != -1) {// 依次读取
char c = (char) temp; // 接收字符
bos.write(Character.toUpperCase(c)); // 输出
}
Character.toUpperCase(c)//将字符转换成大写
String newStr = bos.toString();// 取出内存输出的内容
内存操作流现在在javaSe阶段是感觉不出来的,但是在学习到java WEB的AJAX完成动态效果的时候使用
****管道流(了解流)
管道流就是进行两个线程之间的通讯,使用PipedOutputStream和PipedInputStream两个类完成
这两个类基本和FileInputStream和FileOutputStream差不多
唯一的区别就是在于连接管道的操作上
利用connect进行管道连接
send.getPipedOutputStream().connect(rec.getPipedInputStream()); // 进行管道连接
***********打印流(重点)
想要转换为float数据类型非常麻烦,想要使用方便的输出操作则可以使用打印流
打印流分为两种:
1、PrintStream
2、PrintWrite
PintStream是OutputStream的子类,子类的引用
实际上PrintStream属于装饰,也就是根据实例化PrintStream类的对象不同秘书处的位置也不同,输出的位置也不同
PrintStream out = new PrintStream(new FileOutputStream(file));将OutputStream对象传给PrintStream,这样就可以方便的输出内容
输出操作使用打印流最为方便,以后在输出的时候就使用
、在JDK1.5之后打印流进行了更新,可以使用格式化输出
使用printf方法进行格式化
out.printf("姓名:%s;年龄:%d;成绩:%5.2f;性别:%c。", name, age, score, sex);
******BufferedReader
实际上表示的是缓冲区读取,可以一次性的将内容读取进来
要想使用BufferedReader类接收键盘的输入内容的话,则此时就无法直接实例化了,System.in属于InputStream类型的
在java中提供了两个专门的类,字节-字符类的转换类
1、
在BufferedReader中最重要的一个方法readLine,表示读取一行数据,如果返回的内容是String是最好操作的
BufferedReader buf = null;
// 将字节输入流变为字符输入流放在字符流的缓冲区之中
buf = new BufferedReader(new InputStreamReader(System.in));
*****再程序开发中,必须始终记住一个原则,拥抱变化
最好增加一个过度类
****Scanner类
方边接收数据
可以进行判断输入数据类型
需要设计读取分割符 scan.useDelimiter("\n") ;
******字符编码(重要)
如果在程序中字符编码没有处理完整,则肯定会造成鲁昂吗,常见的编码有以下几种
1、UTF 包含以下编码
2、ISO 8859-1 是包含全部的英文编码
3、GBK/GBK2312 简体中文
System.getProperties().list(System.out) ;
列出本机的一些信息
乱码造成的根本原因就在于本地编码与实际运用的编码不统一
***********对象序列化(重点)
就是将一个对象转换为二进制的数据流,如果一个类的对象要想实现对象序列化,则对象必须实现Serialzable,在此接口中没有任何方法,此接口只是作为一个标识,表示本类的对象具备了序列化的能力而已, 跟cloneable接口一样
如果想要实现对象序列化,主要还是要靠FileOUtputStream和FileInputStream两个类进行序列化
ObjectOutputStream oos = null;
oos = new ObjectOutputStream(new FileOutputStream(file));
Person per = new Person("张三", 30);
oos.writeObject(per) ;将person对象转换成二进制序列化进文件中
对象被序列化之后,就可以被ObjectInputstream进行反序列化
temp = ois.readObject();//反序列化操作
想要让每个属性不能被序列化,那么就使用transient关键字
Object类可以接收任意的引用数据类型,如果想要进行一组对象的序列化操作,那么就使用数组
小结:内存操作流、打印流、System类的三个IO支持
对象序列化(绝对重点)
******类集
类集的概念的是从JDK1.2之后正式完善增加的一套开发架构,其基本作用就是完成了一个动态的对象数组,里面的数据元素可以动态的增加
类集中提供了一下几种接口
单值操作接口,
Collection、List、Set
一对值的操作接口:Map
排序操作接口:sortedMap、SortedSet
输出的接口:Iterator、ListIterator、Enumeration
队列:Queue
从现代的开发中来看,在集合操作中已经很少去使用Collection完成功能了,基本上都使用了其子接口:List、Set
******List接口
lIst接口最大的特点
以下的方法是新增的
add(int index, E element)
在列表的指定位置插入指定元素。
set(int index, E element)
用指定元素替换列表中指定位置的元素
get(int index)
返回列表中指定位置的元素
listIterator()
返回此列表元素的列表迭代器,为listIterator接口实例化
subList(int fromIndex, int toIndex)
返回列表中指定的 fromIndex(包括 )和 toInde(不包括)之间的部分视图
如果要想使用List接口,则要通过其子类,ArrayList、Vector、LinkedList
******新的子类 ArrayList
List<String> allList = new ArrayList<String>();// 为List接口实例化
******旧的子类:Vector
Vector类是一个元老级的操作类埋在JDK1.0推出的时候就有了
其实跟ArrayList一样
List<String> allList = new Vector<String>();// 为List接口实例化
********ArrayList和Vector的区别
ArrayList采用异步的处理操作,Vector采用同步
Arraylist性能较高
********LinkedList和Queue接口(了解)
LinkedList<String> link = new LinkedList<String>() ;
在collection接口中实际上定义了两个方法进行转换为数组
*******集合输出
只要是碰到集合输出,想都不想就使用Iterator接口
*****Iterator(重点)
hasnext方法,判断是否存在值
Iterator<String> iter = allList.iterator();实现接口Iterator
实际开发中一般不会使用Iterator接口进行直接删除,而是使用该接口进行判断是否有值和进行将值输出
******ListIterator
是Iterator的子类
此接口专门为List服务的
hasprevious()方法判断是否有以前的值
previous()取出以前的值
如果要想完成双向输出,则首先一定要保证有有钱向后的操作。
在使用ListIterator接口的时候还可以对内容直接修改
while (iter.hasPrevious()) {
System.out.print(iter.previous() + "、");
}//右后向前输出
*******foreach输出
在数组的输出上,可以使用foreach输出
List<String> allList = new ArrayList<String>();
for (String str : allList) {
System.out.print(str + "、");
}
*******废弃的接口:Enumeration
这个接口只有Vector类才能支持
判断是否还有内容 hasMoreElement()
取出内容:nextElement()
这个接口基本被废弃,不用了
当然对于一些旧的操作类中现在依然支持Enumeration
*****小结
1、List接口中允许有重复元素,而Set则不允许
2、ArrayList和Vector的区别
3、Set依靠hashCode()和equals()方法区分
4、TreeSet按照Comparable接口指定的规则进行排序
5、Map是保存一对值的集合,所有的内容都是以Map Entry的形式进行保存
6、属性操作类使用Properties而立完成
HashSet进行无序的存放
TreeSet进行有序的存放,依靠Comparable接口进行排序的操作
任何非系统类作为Key的话,则必须覆写hashCode和equals方法
str.matches("\\d{4}-\\d{2}-\\d{2}")//验证正则表达式
temp = new SimpleDateFormat("yyyy-MM-dd").parse(str) ;
格式化时间操作
*****类集设置的主要目的,动态的对象数组
************枚举的作用
在C语言中存在一个枚举类型,通过此类型可以限制一个内容的取值范围,但是在JDK1.5之前。java中并不存放枚举的类型,在JDk1.5之后增加的
public enum Color {
RED, GREEN, BLUE;// 定义枚举的取值
}
使用enum关键字声明枚举类型
可以在switch语句中进行判端枚举类型
ordinal()方法得到索引值
name()方法得到值
values方法取得枚举对象-->Enum类
*********Enum类和enum关键字的区别
使用enum关键字可以定义一个枚举类型,哪儿实际上就相当于定义了一个类,此类继承了Enum类而已
******类集对枚举的支持
EmumMap类是Map的子类,操作形式与Map是一致的
EnumMap<Color, String> emap = new EnumMap<Color, String>(Color.class);
******EnumSet
EnumSet是本Set接口的子类,但是是一个单例设计类
方法都是为静态的
EnumSet<Color> eset = null;
eset = EnumSet.allOf(Color.class); // 将所有的内容设置到集合中
******枚举深入,定义构造方法
枚举的使用非常灵活,可以在枚举中直接定义构造方法,但是一旦构造方法定义之后,则所有的枚举对行啊都必须明确的调用此构造方法
就如这样:
Color(String name) {
this.setName(name);
}
RED("红色"), GREEN("绿色"), BLUE("蓝色");
*******枚举实现接口
一个枚举实现一个接口之后,各个枚举对象都必须实现接口中定义的方法
如:在接口中定义了public String getColor();
则枚举对象就要这样:
RED {
public String getColor() {
return "红色";
}
},
*****在枚举中定义抽象方法
在一个枚举中定义了一个抽象方法,则每个枚举对象都要实现
如:public abstract String getColor(); // 定义抽象方法
*****反射机制
在整个java技术中反射技术是最重要的
********认识反射
正常情况下,一个类要想使用,额必须找到此类,之后通过此类产生实例化对象。必须先有类再有对象,那么如果现在想要通过一个对象找到其所在的类呢?
在Object中存在一个getclass方法
所有类的对象都可以使用getclass()方法完成操作,那么此方法返回的是一个Class,anemia通过Class就可以完成反射操作
Person per = new Person(); // 实例化对象
per.getClass().getName()//取得对象所在的包.类的路径
****认识Class类
在反射机制中Class是一个操作的源头,所有的反射操作从此类展开,但是如果要想实例化此类对象可以通过以下的三个途径完成
1、通过getClass方法
2、通过类.class的形式:Person.class
3、通过calss的静态方法forName(),Class.forName("对象所在的包.类的路径")
虽然有3种形式,但是最常用的是forName()方法,其次就是类.class的形式
*****通过Class类实例化对象
在Class的使用中实例化对象是最常用的一种操作,而且哦日后所有的框架各个程序的实现原理都是依靠Class类完成的
******实例化无参构造的类
如果一个类中存在一个无参的构造,那么可以直接通过Class类进行实例化的操作
******实例化调用指定构造的类
如果想要得到全部的够咋方法则使用
getConstructors(); // 得到全部的构造
Constructor类的定义在java.lang.reflect包中,所以属于反射的操作包
newInstance方法,实例化对象
按照参数的个数进行排序,参数越多的构造方法放在最前面
为了开发的简便,一定要在类中定义无参构造方法
*******通过Class类取得完整结构
通过Class类中的很多方法,可以轻易的取得一个类中定义的全部构造方法、普通方法、常量、变量等等
getSuperclass()方法找到其父类
取得实现的全部接口
getInterfaces()接口本身就是一个特殊的类,所以
返回值是一个Class数组
取得当前对象的包名getPackage()
getConstructors(); // 得到全部的构造
getParameterTypes(); // 得到全部的参数
getModifiers(); // 得到修饰符
*******如果想要正确的还原一个反复噶的访问修饰符,则必须使用一个Modifier类进行还原
Modifier.toString(mod);// 还原权限
通过Modifier中tostring方法还原修饰符
******取得一个类中的全部方法
在Class类中的getMethods()方法得到对象中的全部方法
getExceptionTypes(); // 得到全部的异常
getReturnType();// 取得返回值类型
getModifiers(); // 取得访问权限
getReturnType();// 取得返回值类型
取得一个类中的全部属性
Field f[] = c.getFields(); // 取得全部的变量
Field f[] = c.getDeclaredFields(); // 取得全部的变量
******反射的进一步应用
在正常情况下是通过对象.方法()的形式调用类中的方法
// 本程序中将调用Person类中的sayHello()方法
Method met = c.getMethod("sayHello") ;
met.invoke(c.newInstance()) ;
invoke方法表示程序中要真正的执行此方法
属性也是可以通过代码设置访问权限的
*******JDBC的基本概念
JDBC:java Database Connective java数据库连接,是一组专门负责连接并操作数据库的标准。在整个JDBC中实际上大量的提供的是借口,针对于各个不同的数据库生产商,只要想使用java进行数据库的开发,则肯定要对这些标准有所支持
JDBC-ODBC桥连接:是JDK的开发包中提供的最标准的一套JDBC操作类库,一般不会使用,因为会降低性能
JDBC连接,使用各个数据库提供商给定的数据库驱动程序吗,完成JDBC的开发的时候需啊哟在classpath中配置数据库的驱动程序
JDBC网络连接,主要使用通过网络连接数据库
*******JDBC的操作步骤
在进行JDBC操作的时候可以按照以下的步骤完成
1、加载数据库驱动程序,加载的时候需要将驱动程序配置到classpath之中
2、连接数据库,通过Connection接口和Drivermanager类完成
3、操作数据库,通过Statement、preparedStatement、Resultset三个接口完成
4、关闭数据库
*******JDBC的准备工作
先将驱动程序路径配置到classpath之中
如果现在使用Eclipse的话
*******数据库操作
Connection conn = null; // 表示数据库的连接的对象
Statement stmt = null ; // 表示数据库的更新操作
conn = DriverManager.getConnection(DBURL, DBUSER, DBPASS);// 2、连接数据库
// 3、Statement接口需要通过Connection接口进行实例化操作
stmt = conn.createStatement() ;
// 执行SQL语句,更新数据库
stmt.executeUpdate("INSERT ") ;
stmt.addBatch("INSERT ") ;
// 执行SQL语句,更新数据库
int i[] = stmt.executeBatch() ; //返回执行的行数
conn.rollback() ;// 回滚
ResultSet result = null ;// 表示接收数据库的查询结果
result = stmt.executeQuery("SELECT") ;
// 执行SQL语句,查询数据库
result.next()// 是否有下一行数据
int pid = result.getInt("pid") ;//取得pid的值
int pid = result.getInt(1) ;//也可以通过表的行数的排列
******注意的几点******
perseq.nextval oracle中自动增长
TO_DATE oracle中 日期格式化
sysdate oracle中 取得系统时间
*****PreparedStatement
此接口是在实际的开发中使用最广泛的一个操作接口,此接口是Statement接口的子接口,采用预处理的方式完成
PreparedStatement pstmt = null ;// 表示数据库的更新操作
String sql = "INSERT INTO person(pid,name,age,birthday,salary) VALUES (perseq.nextval,?,?,?,?) ";
//先使用?来进行占座
pstmt = conn.prepareStatement(sql) ;// 使用预处理的方式创建对象
pstmt.setString(1, name) ;// 第一个?号的内容
pstmt.setInt(2, age) ; // 第二个?号的内容
pstmt.setDate(3, new java.sql.Date(date.getTime())) ;
pstmt.setFloat(4,salary) ;
// 执行SQL语句,更新数据库
pstmt.executeUpdate();
pstmt.addBatch() ; // 增加批处理
// 执行批处理,更新数据库,并返回受影响的行数
int i[] = pstmt.executeBatch() ;
******事务处理
在JDBC中冶同样存在事务处理
conn.rollback() ;// 事务回滚
conn.commit()进行事务提交
*********网络编程的基本概念
网络,就是将物理不再一起的主机进行互联
在网络上的通讯需要使用协议,常见的通讯协议:Tcp、Udp
Tcp:属于可靠的链接,使用第三方握手的方式完成链接的确认
UDp:是属于不可靠的链接
对于网络程序的开发有两种架构
C/s和B/S