第六讲
异常
知识点
1
什么是异常
jvm
将
java
程序中非正常情况打包成一个对象,这个对象就叫异常
异常的分类:
错误和异常
什么是错误?指的是系统错误,程序无法恢复,比如说找不类,内存益出等
异常:程序中需要被捕获并处理的错误
捕获并处理异常是为了让程序能够正常运行
受查异常,非受查异常,运行时异常
受查异常就是编译时候进行检查的异常
非受查异常是编译的时候不进行检查,
Error
和
RuntimeException
非受查异常:
1
.算术运算错误
java.lang.ArithmeticException
2.
空指针异常
NullPointerException
3
.数组下标越界:
ArrayindexoutofBoundsExction
1.
java
中安全管理器:
这些不让使用
try
因为这些错误是常识,例如除以
0
如何处理异常?
1
.自己处理:
Try
捕获
catch(
异常对象
)
处理
2
.交给别人处理
try cathc
处理一部分
throw
抛出
自定义异常:
继承
Exception
或
RuntimeException
为什么要自定义异常?应用异常,以后开发的时候有应用异常的情况,自己写个业务逻辑的异常
public class Industry {
public static void test(int i,int j){
int rst = 0;
try{
rst=i/j;//
捕获可能发生的异常
}catch(ArithmeticException e){
j=1;
rst=i/j;//
这里处理异常
}
System.out.println(rst);
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Industry a=new Industry();
a.test(10,0);
}
}
错误:
public class TestError {
public void f1(){
f1();
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
TestError t=new TestError();
t.f1();
}
}
package MY.module07;
public class ExceptionDispose {
public static void test(int i,int j){
int rst=0;
try{
rst=i/j;
}catch(ArithmeticException e){
System.out.println(e.getMessage());
// e.printStackTrace();
rst=1;
}
System.out.println(rst);
}
public static void testDispose(int i,int j){
try{
test(i,j);
}catch(ArithmeticException e){
System.out.println("c");
}
}
public static void test2(int i,int j) throws ArithmeticException{
int rst = 0;
// try{
rst = i / j;
// }catch(ArithmeticException e){
System.out.println("wo zi ji chu li yi ban ");
// throw e;
// }
}
public static void testDispose2(int i,int j){
try{
test2(i,j);
}catch(ArithmeticException e){
System.out.println("
不能除以
0");
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
testDispose2(10,0);
}
}
自定义异常
public class InviteException extends Exception{
public InviteException(){
super();
}
public InviteException(String name){
super(name);
}
}
public class TestInviteException {
public static void invite(String name) throws InviteException{
if(name.equals("Japanese")){
throw new InviteException("tong hen can hai wu gu bai xing de Japanese");
}
}
public static void testinvite(){
try{
invite("Japanese");
}catch(InviteException e){
System.out.println(e.getMessage());
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
testinvite();
}
}
处理多个异常:
public class ManExeptionDispose {
public static void test(int i){
if(i==1){
System.out.println("ArithmeticException e");
throw new ArithmeticException("hahahahah");
}
else{
System.out.println("NullPointerException e");
throw new NullPointerException("lalalalalalala");
}
//catch(ArithmeticException e){
// System.out.println(e.getMessage());
// }catch(NullPointerException e){
// System.out.println(e.getMessage());
}
// }
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
try{
test(5);
}catch(Exception e){
System.out.println(e.getMessage());
}
}
}
推荐使用的方式:
public class ManExeptionDispose {
public static void test(int i){
try{
if(i==1){
System.out.println("ArithmeticException e");
throw new ArithmeticException("hahahahah");
}
else{
System.out.println("NullPointerException e");
throw new NullPointerException("lalalalalalala");
}
}catch(ArithmeticException e){
System.out.println(e.getMessage());
}catch(NullPointerException e){
System.out.println(e.getMessage());
}
//catch(ArithmeticException e){
// System.out.println(e.getMessage());
// }catch(NullPointerException e){
// System.out.println(e.getMessage());
}
// }
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
test(5);
}
}
例子:
/**
*
程序目标:
* 1.test:
检测
i=Integer.parseInt(a);
因为可能
i
的类型不匹配,然后自己捕获并
*
干掉异常
*/
package MY.module07;
public class TestUncheckedException {
public static void test(){
String a="100a";
int i=0;
try{
i=Integer.parseInt(a);
}catch(NumberFormatException e){
System.out.println(e.getMessage());
i=100;
System.out.println(i);
}
}
public static void test2(int i){
A a=new A();
B b=a.getObject(0);
if(b!=null)
b.f1();
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
test();
test2(0);
}
}
class A{
B getObject(int i){
B rst=null;
if(i==1){
rst=new B();
}
return rst;
}
}
class B{
void f1(){
System.out.println("f1()");
}
}
处理异常的两种方式:
1
.自己干掉它,也就是被调用者,发生异常的语句
2
.抛给调用者,让他处理,他如果不处理还可以再抛给调用他的地方,最后到
man—jvm
,如果到了
jvm,jvm
会报错
/**java
文件:
* InviteException.java
:自定义异常
* TestInviteException.java:
异常处理
*
知识点:
*
异常的处理方式:两种
1.
自己干掉
2.
交给别人
自定义异常的写法
*
程序目标:
*
自定义一个异常
* 1.test:
发现异常后,抛给别人处理
* 2.test2:
发现异常后,自己将他干掉
* 3.test3:
我处理一部分,然后让调用者处理
*/
package MY.module07.two;
public class TestInviteException{
public static void test(String name) throws InviteException{
if(name.equals("japanese")){
throw new InviteException("wo tao yan japanese!");
}
}
public static void test2(String name){
try{
if(name.equals("japanese")){
throw new InviteException("wo tao yan japanese!");
}
}catch(InviteException e){
System.out.println(e.getMessage());
System.out.println("zi ji gan diao ta");
}
}
public static void test3(String name)throws InviteException{
try{
if(name.equals("japanese")){
System.out.println("tao yan yan ta " );
throw new InviteException("tong hen ta men ");
}
}catch(InviteException e){
System.out.println("chu li yi bu fen ");
throw e;
}
}
public static void InviteTest(String name){
try{
test3(name);
}catch(InviteException e){
System.out.println(e.getMessage());
System.out.println("wo yan wu japanese!");
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
InviteTest("japanese");
}
}
InviteException.java
:自定义异常
public class InviteException extends Exception{
public InviteException(){
super();
}
public InviteException(String s){
super(s);
}
}
重置与异常:
在子类继承父类做方法覆盖的时候,子类可以不抛出异常
子类可以抛其中的一种异常
子类可以全部抛出异常
但是,子类不能抛出范围更广的异常
非受查异常不受这样的限制
子类
throws
的异常类型应该小于等于父类中的异常,非受查异常不受这样的限制
/**
*
知识点:
*
子类继承父类后异常的规则
* java
文件说明:
* ChongzhiA.java:
父类,有一个方法声明并抛出了一个异常
,
证明了非受查异常不受限制
* ChongzhiB.java:
子类,看一下在子类中的重置方法如何写异常的
* TestChongzhi.java:
测试类
*
程序目标:
* 1.test:
证明子类的覆盖方法可以不抛出异常
* 2.test2:
子类可以抛其中的一个异常
,
子类也可以全部的抛出异常
*/
package MY.module07.two;
public class TestChongzhi {
public static void test(int i,int j){
ChongzhiB cb=new ChongzhiB(10, 0);
cb.f1(i,j);
}
public static void test2(int i,int j)throws Exception{
ChongzhiB cb=new ChongzhiB(10, 0);
try{
cb.f2(i,j);
}catch(Exception e){
throw e;
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// test(10,0);
try{
test2(10,0);
}catch(Exception e){
System.out.println(e.getMessage());
}
}
}
ChongzhiA.java
public class ChongzhiA {
private int j;
private int i;
public void f1(int i,int j)throws Exception,ArithmeticException{
int rst=0;
try{
rst=i/j;
}catch(Exception e){
throw e;
}
}
public ChongzhiA(int i, int j) {
super();
// TODO Auto-generated constructor stub
this.j=j;
this.i = i;
}
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
public int getJ() {
return j;
}
public void setJ(int j) {
this.j = j;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return ""+i+""+j;
}
}
ChongzhiB.java
public class ChongzhiB extends ChongzhiA{
public ChongzhiB(int i, int j) {
super(i, j);
// TODO Auto-generated constructor stub
}
public void f1(int i,int j){
}
public void f2(int i,int j)throws Exception{
int rst=0;
try{
rst=i/j;
}catch(Exception e){
throw e;
}
}
public void f3(int i,int j)throws Exception,ArithmeticException,NullPointerException,RuntimeException{//
不能抛出范围更广的异常
int rst=0;
try{
rst=i/j;
}catch(Exception e){
throw e;
}
}
}
finally:
什么是
finally
:用于清理
java
中的资源的,一般放在异常捕捉以后的地方,什么是资源?比如数据库连接对象,套接字,内存空间等等
/**
*
知识点:
* finally:
回收资源
*
程序目标:
* 1.test:
测试
finally
的执行过程
* 2.test2:
测试
finally
中的
return
和
system.exit(0);
* 3.test3:
当程序执行出错,
catch,finally,
剩余代码
*
程序执行出错,若有
return
,对程序执行流程无影响
* 4.test4:
当捕获的异常和在处理中的异常类型不一样,那么程序
*
正常执行
--finally--jvm
抛出异常,报错
*
*/
package MY.module07.two;
public class TestFinally {
/*
*
正常代码
--finally--
剩余代码
*/
public static void test(int i,int j){
int rst=0;
try{
rst=i/j;
}catch(ArithmeticException e){
System.out.println(e.getMessage());
}finally{
System.out.println("zhengli ziyuan ");
}
System.out.println("yu xia dai ma ");
}
/*
*
当没有错误的时候,执行到
return
的时候,先执行
finally
和剩余的
*
代码,然后
return
结束,但如果发生异常了,只执行
finally
程序就
*
结束
*
只有
System.exit(0);
能够阻止
finally
的执行
*/
public static void test2(int i,int j){
int rst=0;
try{
rst=i/j;
return;
}catch(Exception e){
System.out.println(e.getMessage());
}finally{
System.out.println("hui shou zi yuan");
}
System.out.println("sheng yu dai ma");
}
public static void test3(int i,int j){
int rst=0;
try{
rst=i/j;
return;
}catch(Exception e){
System.out.println(e.getMessage());
}finally{
System.out.println("hui shou zi yuan");
}
System.out.println("sheng yu dai ma");
}
public static void test4(int i,int j){
int rst=0;
try{
rst=i/j;
return;
}catch(NullPointerException e){
System.out.println(e.getMessage());
}finally{
System.out.println("hui shou zi yuan");
}
System.out.println("sheng yu dai ma");
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// test(10,0);
// test2(10,1);
// test3(10,0);
test4(10,0);
}
}
构造器与重置相反,因为先调用父类的构造器
断言:
什么是断言?是一种调试的机制,对与布尔值为
false
的地方,允许抛出一个断言性质的异常,什么是调试机制?
debug
,通过断言发现程序中的错误
技巧:
run-vm:
输入
jvm
参数,如:
-ea –da
技巧:虚拟机升到
5.0 windows-preferences-Instaled Jres-add-jdk5.0
断言有开关,在开发测试的时候我们打开它,当部署的时候可以关闭它
-ea,-da
断言的作用:用与
junit
单元测试,
junit
采用的是断言的机制
断言不应该做为程序中的逻辑代码
技巧:点
.java
文件,
new—junit test case
进行
junit
单元测试
/**
*
知识点:
*
断言
*
程序目标:
* test:
测试
assert
的功能
,
当方法返回的值不等于
5
时,报错
*/
package MY.module07.two.asserts;
public class AddOne {
public static int test(int i,int j){
int rst=0;
try{
rst=i/j;
}catch(ArithmeticException e){
System.out.println(e.getMessage());
}
return rst;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int j;
j=test(10,1);
assert j==5:"error";
}
}
/**
*
知识点:
*
断言
*
程序目标:
*
判断
testperson
对象属性是否为
zhaobenshan
,用断言来判断
*/
package MY.module07.two.asserts;
public class TestPerson {
private String name;
public TestPerson(String name) {
super();
// TODO Auto-generated constructor stub
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
TestPerson t=new TestPerson("zhao ben shan");
String s=null;
assert ((s=t.getName())!=null):"error!";
// s=t.getName();
System.out.println(s.length());//assert
里面只是做了判断,并没有给
s
赋值
}
}
/**
*
知识点:
* junit
单元测试,采用的是
assert
机制
* java
文件:
* AddOne.java
*
程序目标:
*
测试
AddOne.java
方法中返回的结果
*
方法:
* AddOneTest.java
右键,点
junit
*/
package MY.module07.two.asserts;
import junit.framework.TestCase;
public class AddOneTest extends TestCase {
public void testAdd(){
int rst=0;
rst=AddOne.test(10,2);
assertEquals(rst,5);//
相当于
assert rst==5
}
}
补充知识
字符串
字符串是对象,属于
immutable
,什么意思呢?就是不可改变的对象
当改变一个
String
对象的时候,等于新建了一个对象,原对象还存在,这样的话,如果我们希望通过
for
循环不段的更改
String
对象的话,就比较麻烦了,产生很多无用的对象,这个时候我们使用
StringBuffer
类对象来解决这个问题,他和
String
的区别就是,
StringBuffer
它是可以改变的,能够保障对象的唯一
StringTokenizer
类,它在
java.util
包下,实现了字符串分割的算法
/**
*
知识点:
* StringBuffer,String,StringBuffer.append
方法
*
程序目标:
*
说明
StringBuffer
和
String
的区别
*/
package MY.module1_7.StringK;
public class TestStringBuffer {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
/**
*
通过
append
方法可以修改
StringBuffer
对象
*
这个时候只产生了两个对象,如果用
String
产生
1001
个对象
*/
StringBuffer sb=null;
sb=new StringBuffer("akdhfkh");
System.out.println(sb);
for(int i=0;i<1000;i++){
sb.append("a");
}
System.out.println(sb);
//
可以修改
StringBuffer
对象,他是
mutable
的,对象可以改变
String s1="abc";
String s2="123";
StringBuffer sb1=new StringBuffer(s1);
StringBuffer sb2=new StringBuffer(s2);
sb1.append(sb2);
System.out.println("sb1="+sb1);
System.out.println("sb2="+sb2);
StringBuffer sb3=new StringBuffer("Hello");
sb3.append(" world ");
sb3.append("!");
String s=sb3.toString();//
把
sb3
中的字符串转换为值
System.out.println(s);
}
}
/**
*
知识点:
* String:String
池,
String
的创建
,String
特点,
String
常用比较的方法
*
程序目标:
*
验证
String
的特点和作用
*/
package MY.module1_7.StringK;
public class TestString {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String s1=new String("hello");
String s2=new String("hello");
boolean rst=s1==s2;
System.out.println(rst);//
假,因为在堆区开了两个空间,内容都是
hello
System.out.println(s1.equals(s2));//
真,因为比较的是内容
String s3="hello";
String s4="hello";
boolean rst2=s3==s4;
System.out.println(rst2);//
真,在字符串池中,只有
hello
一个实例
String s5="abc";
String s6="xyz";
s5=s6;//
都指向同一个对象
xyz
s5=s5+"abc";
System.out.println("s5="+s5+"s6="+s6);//String
是
immutable
的,对象不可改变
//
类似数组,编号从
0
开始
System.out.println("s6.indexof(f) "+s6.indexOf("y"));
//
常用的比较方法
//equals
//equalsIgnoreCase
//compareTo
}
}
/**
*
知识点:
* String
类的常用方法(
chatAt,subString,indexOf
)
*
程序目标:
*
测试
String
类的方法
*/
package MY.module1_7.StringK;
public class TestString2 {
public static void test(){
String s="hello world";
System.out.println(s.charAt(1));
System.out.println(s.substring(5));//
从空格截取到末尾的字符,包括空格
System.out.println(s.substring(1,6));//
尾部不包含
6
System.out.println(s.indexOf("lo"));
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
test();
}
}
/**
*
知识点:
* StringTokenizer
类
:
是一个算法类,用来分割字符串的
*
程序目标:
*
写一个分割字符串的方法,这个方法的算法实现用
StringTokenizer
类
*
然后
man
方法中写个字符串,调用这个方法,实现字符串分割,并生成
*
数组,打印出分割后的元素
*/
package MY.module1_7.StringK;
import java.util.*;
public class StringTokenTest {
public static String[] spit(String a,String x){
String[] rst=null;
StringTokenizer s=new StringTokenizer(a,x);
rst=new String[s.countTokens()];
int index=0;
while(s.hasMoreTokens()){
rst[index]=s.nextToken();
index++;
}
return rst;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String s="hello world";
String[] a=spit(s," ");
for(int i=0;i<a.length;i++){
System.out.println(a[i]);
}
}
}
/**
*
知识点:
* math
类
:long
包下的类,不能被继承,里面有常用的数学算法
*
如:绝对值,四舍五入等等
*/
package MY.module1_7.math;
public class TestMath {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(Math.E);
System.out.println(Math.PI);
System.out.println(Math.abs(-89));
System.out.println((int)(100*(Math.random())));
System.out.println(Math.sqrt(10.232323));
}
}
/**
*
知识点:
*
包装类的使用
*
程序目标:
*
测试包装类
*/
package MY.module1_7.Wrapper;
public class TestWrapper {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Integer i1 = new Integer(1);
int x1 = i1.intValue();
Integer i2 = new Integer("2");
int x2 = i2.intValue();
int x3 = Integer.parseInt("3");
Boolean b1 = new Boolean("true");
Boolean b2 = new Boolean("True");
Boolean b3 = new Boolean("boolean");
System.out.println("x1= " + x1 + " x2= " + x2 + " x3= " + x3);
System.out.println("b1= " + b1 + " b2= " + b2 + " b3= " + b3);
System.out.println("i1= " + i1);
Integer one = new Integer(1);
System.out.println("i1.equals(one)= " + i1.equals(one));
Integer i3 = new Integer("a");// runtime exception
}
}
克隆
clone
什么是克隆?复制对象,复制对象中的属性,复制一个类等
平时我们怎么克隆对象的呢?
A a=new A();
A a1=a;
这样的话,当我们改变对象的属性值的时候,原来那个也就改变了,这样不符合我们的要求,我希望克隆一个一样的对象,但是当我改变克隆对象的属性方法的时候,原来的那个不会改变,这个时候,我们需要使用
object
类定义的
clone
方法
当我们用某个对象的克隆方法的时候,需要让类实现
cloneable
接口,这个接口没有声明任何方法,只是告诉类,已经可以使用克隆技术了,然后,我们我们重写
clone
方法,改为
public
的
/**
*
知识点:
*
克隆
clone
* java
文件说明:
* Student.java
:学生类
* TestClone.java man
方法类
复制一个学生对象,对比以下内容是否一样
*
程序目标:
*
造一个学生,然后复制这个学生,有同样的属性,方法
*
要求修改复制者不能影响原本
*/
package MY.module1_7.clone;
public class TestClone {
public static void test(){
Student s1=new Student("liu",20);
Student s2=new Student();
s2.setAge(s1.getAge());
s2.setName(s1.getName());
System.out.println(s2.equals(s1));
s2.setAge(30);
System.out.println(s2.equals(s1));
}
public static void test2(){
Student s1=new Student("liu",20);
Student s2=null;
try {
s2=(Student)(s1.clone());
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(s2.equals(s1));
s2.setAge(30);
System.out.println(s2.equals(s1));
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// test();
test2();
}
}
package MY.module1_7.clone;
public class Student implements Cloneable{
private String name;
private int age;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public boolean equals(Object arg0) {
// TODO Auto-generated method stub
boolean rst=false;
if(arg0 instanceof Student){
Student stu=(Student)arg0;
if(name.equals(stu.name)&&age==stu.age){
rst=true;
}
}
return rst;
}
@Override
public String toString() {
StringBuffer sb=new StringBuffer();
sb.append(name);
sb.append(age);
return sb.toString();
}
}
/**
*
知识点:
* clone:
深复制:就是把一个类对象中的属性也复制了
*
因为如果这个属性是引用类型的话,那么他们在复制的时候会指向
*
同一个地址,这样你修改他等于修改原来的对象了,这不符合我们的要求
*
所以,我们必须也要把这个属性也复制一下
* java
文件说明:
* Student.java:
学生类,里面有个属性是引用类型的,
Toy
类型的属性
* Toy.java:
这个类中也要实现
cloneable
接口,和
clone
方法
* TestClone.java:
复制一个学生对象,然后改复制品,再看看有没有修改
*
到原对象,如果没有被修改就达到要求了
*/
package MY.module1_7.clone.clone2;
public class TestClone {
public static void test(){
Student s1=new Student("li",20,new Toy("nana",2000));
Student s2=null;
try {
s2=(Student)s1.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(s1);
System.out.println(s2);
s2.getToy().setToyName("benben");
System.out.println(s1);
System.out.println(s2);
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
test();
}
}
package MY.module1_7.clone.clone2;
public class Student implements Cloneable{
private String name;
private int age;
private Toy toy;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
// TODO Auto-generated constructor stub
this.name = name;
this.age = age;
}
public Student(String name, int age, Toy toy) {
super();
// TODO Auto-generated constructor stub
this.name = name;
this.age = age;
this.toy = toy;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Toy getToy() {
return toy;
}
public void setToy(Toy toy) {
this.toy = toy;
}
@Override
public Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
Student stu=null;
stu=(Student)super.clone();
stu.toy=(Toy)toy.clone();//
因为
toy
是引用类型,所以也要复制
return stu;
}
@Override
public boolean equals(Object arg0) {
// TODO Auto-generated method stub
boolean rst=false;
if(arg0 instanceof Student){
Student stu=(Student)arg0;
if(name.equals(stu.name)&&age==stu.age){
rst=true;
}
}
return rst;
}
@Override
public String toString() {
// TODO Auto-generated method stub
StringBuffer sb=new StringBuffer();
sb.append(name);
sb.append(age);
sb.append(toy);
return sb.toString();
}
}
package MY.module1_7.clone.clone2;
public class Toy implements Cloneable{
private String toyName;
private double price;
public Toy(String toyName, double price) {
super();
// TODO Auto-generated constructor stub
this.toyName = toyName;
this.price = price;
}
public Toy() {
super();
// TODO Auto-generated constructor stub
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getToyName() {
return toyName;
}
public void setToyName(String toyName) {
this.toyName = toyName;
}
@Override
public Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
@Override
public boolean equals(Object arg0) {
boolean rst=false;
if(arg0 instanceof Student){
Toy t=(Toy)arg0;
if(toyName.equals(t.toyName)&&price==t.price){
rst=true;
}
}
return rst;
}
public String toString() {
StringBuffer sb=new StringBuffer();
sb.append(toyName);
sb.append(price);
return sb.toString();
}
}
垃圾收集
什么是垃圾收集?有什么用呢?
Jvm
会有一个垃圾收集的线程,用来回收那些没有用的对象,什么是没有用的对象?就是没有引用类型指向的对象,那么这个对象需要被回收
技巧:
-verbosegc:
显示垃圾回收的参数,在
jvm
输入框中输入
system.gc();
通知垃圾回收线程可以收集垃圾了,一般情况下,马上回收
finalize
方法:
遗言,就是对象死以前会告诉
finalize
信息,然后
finalize
会把它打印出来
,jvm
会调用他
/**
*
知识点:
*
垃圾回收:
System.gc();
通知
jvm
开始回收垃圾,垃圾就是没有用的
*
对象,也就是没有任何引用指向的对象
*
程序目标:
*
验证垃圾的回收
*/
package MY.module1_7.garbage;
public class FirstGC {
FirstGC(){
System.out.println("firstgc");
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new FirstGC();
System.gc();
}
}
/**
*
知识点:
*
垃圾回收的过程,什么情况下垃圾回收?
*
程序目标:
*
证明垃圾回收的过程与情况
*/
package MY.module1_7.garbage;
public class Garbage {
public void test(){
TV tv1=new TV();
TV tv2=new TV();
tv1=tv2;
tv1.a=100;
TV tv3=new TV();
tv1=null;
tv3=null;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new Garbage().test();
}
}
class TV{
int a;
}
/**
*
知识点:
* finalize()
这个是在父类定义的,需要重写它,对象死的时候给留的遗言
*
这个方法是在垃圾回收后,
jvm
调用
finalize
这个方法的,然后再执行剩余
*
的代码
*
程序目标:
*
测试
finalize
方法和垃圾回收的全过程
*/
package MY.module1_7.garbage;
public class TestFinalize {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new TestFinalize();
new TestFinalize();
System.gc();
System.out.println("ggggggg");
}
@Override
protected void finalize() throws Throwable {
// TODO Auto-generated method stub
System.out.println("adsfasdfadf");
}
}
回调:
什么是回调?当一个类调用自己的一个方法的时候,在这个方法里面,需要另一个类或接口中的一个方法返回的值的时候,这种写法叫做回调
/**
*
知识点:
*
回调:在
collection
类的
sore
方法中调用了
list
容器中的对象类中的
*
自定义排序规则的一个方法,这个方法返回了一个
int
的值,在
sore
*
方法中按
int
的值对对象进行排序,这是回调机制
* java
文件:
* Student.java:
学生类
*
程序目标:
*
测试系统中的回调机制
*/
package MY.module1_7.callback.p1;
import java.util.*;
public class Testcallback {
public static void test(){
List list=new ArrayList();
Student s1=new Student("li",20);
Student s2=new Student("liu",20);
Student s3=new Student("lisi",23);
Student s4=new Student("zhang",21);
Student s5=new Student("zhang",28);
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
list.add(s5);
Collections.sort(list);
System.out.println(list);
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
test();
}
}
Student.java:
package MY.module1_7.callback.p1;
import java.util.*;
public class Student implements Comparable{
private String name;
private int age;
public Student(String name, int age) {
super();
// TODO Auto-generated constructor stub
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object arg0) {
// TODO Auto-generated method stub
boolean rst=false;
if(arg0 instanceof Student){
Student stu=(Student)arg0;
if(name.equals(stu.name)&&age==stu.age){
rst=true;
}
}
return rst;
}
@Override
public String toString() {
// TODO Auto-generated method stub
StringBuffer sb=new StringBuffer();
sb.append(name);
sb.append(":");
sb.append(age);
return sb.toString();
}
public int compareTo(Object arg0) {
// TODO Auto-generated method stub
int rst=0;
rst=age-((Student)arg0).age;
if(rst==0){
rst=name.hashCode()-((Student)arg0).hashCode();
}
return rst;
}
}
/**
*
知识点:
*
自己写个回调的机制
* java
文件说明:
* MyCollections.java
:使用冒泡法将
list
容器中的对象排序,实现了
sore
方法
* MYComparator.java:
接口,里面声明了排序规则方法
* Mycompare.java:
实现了
MYComparator
中方法的类,写了排序的规则
* Student.java:
学生类
*
程序说明:
*
使用
list
容器管理对象,使用
MyCollections
类的
sore
方法实现了对学生的
*
排序,排序规则在实现了比较器接口的类中定义的,然后学生类继承了
*
比较器类,注意,学生类可以直接实现比较器接口
*/
package MY.module1_7.callback.p2;
import java.util.*;
public class Testcallback {
public static void test(){
// Mycompare mc=new Mycompare();
List list=new ArrayList();
Student s1=new Student("li",23);
Student s2=new Student("li",22);
Student s3=new Student("zhang",28);
Student s4=new Student("zhang",28);
Student s5=new Student("zhang",30);
Student s6=new Student("zhang",28);
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
list.add(s5);
list.add(s6);
MyCollections.mySore(list);
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
test();
}
}
Student.java:
package MY.module1_7.callback.p2;
import java.util.*;
public class Student extends Mycompare{
private String name;
private int age;
public Student(String name, int age) {
super();
// TODO Auto-generated constructor stub
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object arg0) {
// TODO Auto-generated method stub
boolean rst=false;
if(arg0 instanceof Student){
Student stu=(Student)arg0;
if(name.equals(stu.name)&&age==stu.age){
rst=true;
}
}
return rst;
}
@Override
public String toString() {
// TODO Auto-generated method stub
StringBuffer sb=new StringBuffer();
sb.append(name);
sb.append(":");
sb.append(age);
return sb.toString();
}
}
MyCollections.java:
package MY.module1_7.callback.p2;
//(MYComparator)(list.get(j+1))
import java.util.*;
public class MyCollections {
public static void mySore(List list){
for(int i=0;i<list.size();i++){
for(int j=0;j<list.size()-i-1;j++){
if(((MYComparator)(list.get(j))).compare(list.get(j+1))>0){
MYComparator mc=null;
mc=(MYComparator)(list.get(j));
list.set(j, list.get(j+1));
list.set(j+1,mc);
}
}
}
System.out.println(list);
}
}
MYComparator.java:
package MY.module1_7.callback.p2;
public interface MYComparator {
int compare(Object obj);
}
MYComparator.java
package MY.module1_7.callback.p2;
public class Mycompare implements MYComparator{
public int compare(Object obj) {
// TODO Auto-generated method stub
Student st=(Student)obj;
Student st2=(Student)this;
int rst=0;
rst=st.getAge()-st2.getAge();
if(rst==0){
rst=st.getName().hashCode()-st2.getName().hashCode();
}
return rst;
}
}
单例模式
什么是单例模式?
只有唯一的对象,只能创建一个对象,叫单例模式
有什么用呢?
可以保护系统的资源,不至于让用户创建太多的对象,造成浪费
怎样实现单例模式呢?
第一,
构造器私有化
第二,
唯一的实例由该类自己实现
第三,
通过一个公开的方法,让外界得到这个实例
/**
*
知识点:单例模式
* java
文件说明:
* Student.java:
私有化了构造器,并在自己的类中实现了唯一的
Student
*
实例
* TestDesigns:
测试
Student
中的单例
*
程序目标:
*
使用单例模式得到一个学生,并设置打印它的姓名
*/
package MY.module1_7.designs;
public class TestDesigns {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Student s=Student.f();
s.setName("liuxin");
System.out.println(s.getName());
}
}
Student.java:
学生类
package MY.module1_7.designs;
public class Student {
private static Student stu=new Student();
private String name;
private Student(){
}
public static Student f(){
return stu;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
工厂模式
什么是工厂?生产对象的对象,封装了对象的生产细节
例如:生产汽车,需要一个生产汽车的工厂,客户(客户端)需要买汽车,直接和销售联系就可以了,不需要知道生产细节,工厂还要分很多的车间,有很多的生产线,如,宝马车间,奔驰车间等等
开闭原则:什么是开闭原则?一个软件实体(对象,模块)应该对扩展开发,对修改关闭,可以扩展以前的东西,但是不能修改,主体不能修改
简单工厂模式:
/**
*
知识点:
*
简单工厂模式,
String
* java
文件说明:
* Car.java
* CarFactory.java
* Benz.java
* BMW.java
* StringSplit.java
*
程序目标:
*
从命令行接受字符串,分割这些字符串
*
判断这些字符串,如果是
bmw
就造个宝马出来
..
*/
package MY.module1_7.designs.Factory.f1;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String s1=args[0];
String s2=args[1];
String s3=args[2];
String[] rst=null;
rst=StringSplit.split(s1,s2);
for(int i=0;i<rst.length;i++){
String s=rst[i];
CarFactory.factory(s,s3);
}
}
}
Benz.java
package MY.module1_7.designs.Factory.f1;
public class Benz extends Car{
private String name;
private String xinghao;
private double price;
public Benz() {
super();
// TODO Auto-generated constructor stub
}
public Benz(String name, String xinghao, double price) {
super();
// TODO Auto-generated constructor stub
this.name = name;
this.xinghao = xinghao;
this.price = price;
System.out.println(this);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getXinghao() {
return xinghao;
}
public void setXinghao(String xinghao) {
this.xinghao = xinghao;
}
@Override
public boolean equals(Object arg0) {
// TODO Auto-generated method stub
boolean rst=false;
if(arg0 instanceof Benz){
Benz bz=(Benz)arg0;
if(name.equals(bz.name)&&xinghao.equals(bz.xinghao)&&price==bz.price){
rst=true;
}
}
return rst;
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
int a=new Double(price).hashCode()^+name.hashCode()+xinghao.hashCode();
return a;
}
@Override
public String toString() {
// TODO Auto-generated method stub
StringBuffer sb=new StringBuffer();
sb.append(name+" ");
sb.append(xinghao+" ");
sb.append(price);
return sb.toString();
}
}
BMW.java
package MY.module1_7.designs.Factory.f1;
public class BMW extends Car{
private String name;
private String xinghao;
private double price;
public BMW() {
super();
// TODO Auto-generated constructor stub
}
public BMW(String name, String xinghao, double price) {
super();
// TODO Auto-generated constructor stub
this.name = name;
this.xinghao = xinghao;
this.price = price;
System.out.println(this);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getXinghao() {
return xinghao;
}
public void setXinghao(String xinghao) {
this.xinghao = xinghao;
}
@Override
public boolean equals(Object arg0) {
// TODO Auto-generated method stub
boolean rst=false;
if(arg0 instanceof Benz){
BMW bz=(BMW)arg0;
if(name.equals(bz.name)&&xinghao.equals(bz.xinghao)&&price==bz.price){
rst=true;
}
}
return rst;
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
int a=new Double(price).hashCode()^+name.hashCode()+xinghao.hashCode();
return a;
}
@Override
public String toString() {
// TODO Auto-generated method stub
StringBuffer sb=new StringBuffer();
sb.append(name+" ");
sb.append(xinghao+" ");
sb.append(price);
return sb.toString();
}
}
Car.java
package MY.module1_7.designs.Factory.f1;
public class Car {
}
CarFactory.java
package MY.module1_7.designs.Factory.f1;
//
制作汽车
public class CarFactory {
public static void factory(String s,String s3){
String[] rst=null;
rst=StringSplit.split(s,s3);
if(rst[0].equals("bmw")){
BMW bmw=new BMW(rst[0],rst[1],Double.parseDouble(rst[2]));
}else if(rst[0].equals("benz")){
Benz ben=new Benz(rst[0],rst[1],Double.parseDouble(rst[2]));
}else{
System.out.println("wo men bu xiao shou ci che");
}
}
}
StringSplit.java
package MY.module1_7.designs.Factory.f1;
import java.util.*;
public class StringSplit {
public static String[] split(String s1,String s2){
String[] rst=null;
int cout=0;
int i=0;
StringTokenizer st=new StringTokenizer(s1,s2);
cout=st.countTokens();
rst=new String[cout];
while(st.hasMoreTokens()){
rst[i]=st.nextToken();
i++;
}
return rst;
}
}
/**
*
知识点:
*
简单工厂模式:有一个工厂类来造对象,但是当业务需求发生变化时
*
还是要改动工厂类中的一些代码,这样违背了工厂模式的初衷,也没有
*
体现
Java
的多态
* Java
文件说明:
* Benz.java BMW.java Car.java CarFactory.java(
工厂类
) Test.java
*
程序目标:
*
调用工厂类的一个方法,并给这个方法传递一个汽车的名字,工厂类的
*
这个方法判断你想要什么车,然后制作出来,也就是
new
个对象出来
*
并调用该对象的
run
方法,用多态的形式调用
run
这个方法
*/
package MY.module1_7.designs.Factory.f2;
public class Test {
public static void main(String[] args){
Car car=CarFactory.Factory("BMW");
try{
car.run();
}catch(NullPointerException e){
System.out.println(e.getMessage());
}
}
}
Car.java
package MY.module1_7.designs.Factory.f2;
public abstract class Car {
public abstract void run();
}
Benz.java
package MY.module1_7.designs.Factory.f2;
public class Benz extends Car{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Benz's run......");
}
}
BMW.java
package MY.module1_7.designs.Factory.f2;
public class CarFactory {
public static Car Factory(String s){
Car car=null;
if(s.equalsIgnoreCase("bmw")){
car=new BMW();
}else if(s.equals("benz")){
car=new Benz();
}else
System.out.println("mei sheng chan ci che");
return car;
}
}
CarFactory.java
package MY.module1_7.designs.Factory.f2;
public class CarFactory {
public static Car Factory(String s){
Car car=null;
if(s.equalsIgnoreCase("bmw")){
car=new BMW();
}else if(s.equals("benz")){
car=new Benz();
}else
System.out.println("mei sheng chan ci che");
return car;
}
}
为什么叫简单工厂呢?因为上面那两个程序如果要加上另一个品牌的汽车的话,是不是需要修改工厂类啊,这样的话违背了工厂模式的初衷,也违背了多态的思想
/**
*
知识点:
*
工厂方法:工厂类下有几个车间类,每个车间针对一种产品类,这样
*
如果增加生产品种的话,不用在工厂类中修改,只需要添加一个生产线
*
就可以了
* Java
文件说明:
* CarFactory.java(
工厂
) BMWCarFactory(
宝马车间
) BenzCarFactory(
奔驰车间
)
* Car.java Benz.java BMW.java Test.java
*
程序目标:
*
客户要什么汽车,工厂马上生产什么汽车出来,要求工厂类不能改变
*/
package MY.module1_7.designs.Factory.f3;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
CarFactory carg=new BMWCarFactory();
Car car=carg.Factory();
try{
car.run();
}catch(NullPointerException e){
e.printStackTrace();
}
}
}
package MY.module1_7.designs.Factory.f3;
public class CarFactory {
public Car Factory(){
return null;
}
}
package MY.module1_7.designs.Factory.f3;
public class BMWCarFactory extends CarFactory{
public Car Factory(){
return new BMW();
}
}
package MY.module1_7.designs.Factory.f3;
public class BenzCarFactory extends CarFactory{
public Car Factory(){
return new Benz();
}
}
package MY.module1_7.designs.Factory.f3;
public abstract class Car {
public abstract void run();
}
package MY.module1_7.designs.Factory.f3;
public class Benz extends Car{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("benz");
}
}
package MY.module1_7.designs.Factory.f3;
public class BMW extends Car{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("bmw's run");
}
}
这个程序以后再添加个
qq
或者其他品牌,只是在原基础上扩展就可以了,不用在工厂类中修改了
包的概念
1.package
的作用:
(
1
)更好的组织类
(
2
)减少类名的冲突
(
3
)访问控制机制
2.
使用注意事项
(
1
)使用
package
关键字指明类所在的包
(
2
)
package
语句必须在文件的最前面
(
3
)编译时可使用
javac -d
路径
源文件名
.java
自动产生包目录
(
4
)使用
java
包名
.
类名执行。
3.import
的作用
(
1
)直接引用指定的类
(
2
)引用一个包中的多个类
(
3
)
*
代替类名,不能代替包名
(
4
)
import
在所有类之前,在
package
之后
(
5
)
import
只是告诉编译器及解释器哪里可找到类,变量,方法的定义,并没有将这些定义引入代码中。
4.
怎样使用包中的类
(
1
)
java.lang
包,不用引入
(
2
)如果引入的不同的包中包含相同的类名
那么这些类的使用必须加上包名
/**
*
知识点:
*
包:倒入包
* java
文件说明:
* p1
包下
:A.java B.java
*
程序目标:
*
使用其它包的对象
*/
package MY.module1_7.Package;
import MY.module1_7.Package.p1.*;;
public class TestPackage {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
A a=new A();
B b=new B();
a.fa();
b.fb();
}
}
其他包下的
A.java
package MY.module1_7.Package.p1;
public class A {
public void fa(){
System.out.println("fa");
}
}
其他包下的
B.java
package MY.module1_7.Package.p1;
public class B {
public void fb(){
System.out.println("fb");
}
}
继承,抽象类,接口知识补充
/**
*
知识点:
*
继承
* java
文件说明:
* People.java Student.java(
有学习的方法
)
* Teacher.java
(有教书的方法)
Test.java TS.java
(重新写了学习和教书的方法)
*
程序目标:
*
有个一个人类,有两个学生和老师类,都继承了人类,分别有不同的方法
*
这时,如果需要写个继有老师又有学生的方法的类,因为继承不没有多
*
继承,所以,如果非要按继承来写的话,只能继承人类,然后在重新写
*
学习和教书这两个方法
*/
package MY.module1_7.extends2.p1;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
TS ts=new TS();
ts.stu();
ts.teaing();
}
}
package MY.module1_7.extends2.p1;
public class TS extends People{
@Override
public void eat() {
// TODO Auto-generated method stub
}
public void stu(){
System.out.println("xuexi .....");
}
public void teaing(){
System.out.println("jiao shu");
}
}
如果再写一个又能学习,又能教书,而且会唱歌的类,还是得从新写这些方法,这样就很不方便了,违背了代码的重用原则
/**
*
知识点:
*
接口
* java
文件说明:
* Actar.java
(接口)
Student.java
和
Teacher.java
(实现了
Actar
接口)
* People.java
(用于终端,可以通过里面的
Vector
加入新的对象,这样就有更多的功能了)
*
程序目标:
*
解决了当需要一个对象,又有学生的方法,又有老师的方法必须再次重新
*
写方法的问题,提高了代码的简洁性,体现了重用思想
*/
package MY.module1_7.extends2.p2;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
People p=new People();
p.add(new Student());
p.add(new Teacher());
//
这样就可以使用
s
和
t
这两个方法了,只需要扩展,不用修改其他的代码
}
}
package MY.module1_7.extends2.p2;
import java.util.*;
public class People {
private Vector v=new Vector();
public void add(Actar a){
v.add(a);
}
public void remv(Actar a){
v.remove(a);
}
}
package MY.module1_7.extends2.p2;
public interface Actar {
}
package MY.module1_7.extends2.p2;
public class Student implements Actar{
public void s(){
System.out.println("student....");
}
}
package MY.module1_7.extends2.p2;
public class Teacher implements Actar{
public void t(){
System.out.println("teacher.....");
}
}
总结:当我们需要一个类中写共有方法的时候,我们写抽象类,除此之外,我们都用接口
接口可以解决多继承的问题
注意:编译的时候确定属性,运行的时候确定方法,静态方法,属性不被继承