1—Object
Object是所有类的根类,称为上帝类。
该类中定义的是所有对象都具备的功能。
所有类都继承这个方法。相当于class Demo extends Object.
所有对象都实现这个类的方法。Object类中常见方法:
boolean obj.equals(Object oo); //比较两个对象是否是同一个对象。 Class<> obj.getClass(); //获取该Object的运行时类。 int obj.hashCode(); //获取该对象的哈希值。 String obj.toString(); //返回该对象的字符串表示形式,一般是引用。 void wait(); //当前对象线程等待。 void wait(long time); //当前对象线程等待指定时间。 void notify(); //唤醒在该对象上等待的线程。 void notifyAll(); //唤醒所有等待线程。
Object类中定义的都是所有类都应该具有的功能,如比较功能,转为字符串功能,求哈希值等。
但是有时候对象只是引用,这时候最好不直接比较引用是否相等,而是由子类复写该方法,以达到比较内容的目的。举例:
class Demo // extends Object { private int num; Demo(int num) { this.num=num; } public boolean equals(Object oo)//复写时,参数必须是Object类型。 { if (!(oo instanceof Demo)) //判断是否是同一类型对象,如果不是,不用比较。 return false; Demo d=(Demo)oo; //对象类型从Object类型向下转型,以便于比较内容。 return this.num==d.num; } } class Object Demo { public static void main(String [] args) { Demo d1=new Demo(2); Demo d2=new Demo(2); System.out.println(d1.equals(d2));//Demo类复写了Object 类中的equals方法,用于比较内容。 } }
2—package
package特点:
写在程序文件代码的第一行。
包名的所有字母小写。
它是一种封装形式。带包的类文件在编译时,要在javac前加参数。
如,javac -d . packageDemo.java。 //-d 是指目录,目录中存放编译后的class文件;文件夹名为类文件中package 后的名称。
运行时写
java pack.packageDemo 。
一个项目是由很多类组成。加上package可以分类文件。
所以包的出现可以让类文件和源文件相分离。方便多机使用,只要copy类文件就行。修饰符权限问题表:
public protected default private 同一类中 OK OK OK OK 同一包中 OK OK OK 子类中 OK OK 不同包中 OK
举例::
A类:package packa; public class A { public static void main(String [] args) { packb.A a=new packb.A();//调用另一个带包的类中的方法,类名前需要加包名。 a.show(); } }
B类:
package packb; protected class B { public void show() { System.out.println("show"); } }
C类:
package packc; public class C extends packb.B //C类继承了B类,所以可以使用被protected修饰的B类。 { public void run() { System.out.println("run"); show(); //调用继承过来的show()方法。 } }
注意:
(1)调用一个包中的类和方法时,必须要有足够大的权限,所以类和方法都要被 public 修饰。
(2)被调用的包需要先生成class文件,并且需要设置 classpath 告诉虚拟机去哪里找这个类文件所在的包。
(3)C类继承了B类,所以C可以访问B中的protected修饰的show方法,而A类不继承B类,所以不能访问B类中方法。
(4)这就是 protected 的作用:只能是它的子类才可以使用它的内容。
(5)源文件中如果不写package的话,会直接在指定目录生成class文件,而不是先创建文件夹。import:导包
import紧接package下一代码行写。
对于多层包目录: pack.aa.bb.cc;
它在 new 对象时,要写成pack.aa.bb.cc.Demo d = new pack.aa.bb.cc.Demo();
为了简化书写,所以可以导包:
import pack.hahaha.haha.ha.Demo.class 。
简化之后,代码可以写成 :
Demo d=new Demo();
如果要导入的类文件比较多的话,可以用*代替类文件名,导入目录中所有的类文件,如:
import java.aa.bb.cc.*;
注意:
(1)如果导入包之后有重复类,必须要声明是哪个包中的。
(2)不同包中的类同名时,调用时类必须加包名。import导入的是包中的类,形式如:
C:\class\pack\aaa\Demo1.class C:\class\pack\aaa\bb\c\Demo2.class
如果导入 import pack.aaa.*; 则只导入了Demo1.class。
import pack.aaa.bb.c.*; 才能导入 Demo2.class。
建议不写*通配符,易占用内存空间。jar : 压缩包
jar包可以将一个文件夹下的多个文件夹压缩成一个后缀为.jar的包。
如:
将c:\class 文件夹下的packa,packb文件夹用jar工具压缩成packab包。
(1)先切换目录到c:\class下;
(2)压缩命令 : jar -cf packab.jar packa packb
会在下生成一个packab.jar de 压缩文件。
(3)查看jar包的归档信息:jar -tf packab.jar
(4)导出文字较多的信息:jar -tf packab.jar >c:\class\123.txt
会在c:\class 下生成123.txt,包含详细的归档信息(数据重定向)。jar中的常用关键字:
-c 创建新档案 -t 列出档案目录 -x 从档案中提取指定的 (或所有) 文件 -v 在标准输出中生成详细输出 -f 指定档案文件名 -m 包含指定清单文件中的清单信息 -C 更改为指定的目录并包含以下文件
对于jar包中的文件,可以直接java命令执行。
如:jar包中的 packa\Demo.class
可以直接调用命令 java packa.Demo 运行。
3—Exception
异常就是程序在运行时出现不正常情况。或者说是对不正常情况进行描述后的对象体现。
java中把异常通过java的类的形式进行描述,并封装成对象。异常把问题划分成两部分:
1.严重的问题。
java中通过Error类进行描述。对于Error一般不编写针对性的代码对其进行处理。
2.不严重的问题。
java中通过Exception类进行描述。对于Exception可以使用针对性处理方式进行处理。异常的格式:
try { 需要被检测的代码; } catch(异常类 异常变量) { 处理异常的代码; } finally { 一定会执行的语句;//一般是关闭资源的代码。 }
注意:
(1)finally 只有一种情况是执行不到的,就是前面执行到了 System.exit(0);表示JVM系统退出。
(2)finally{} 和 catch{}只能有一个可以省略不写, try 必须写。
(3)catch 的前面必须是 try{},finally 的前面也是要紧跟 try{}或者 catch(){}。
(4)try语句中,程序一旦发生异常,就不再继续执行而是直接跳转到catch语句中。Exception常见子类关系图:
ClassNotFoundException 类未找到异常 DataFormatException 数据格式异常 InterruptedException 中断异常 IOException IO流异常 NoSuchMethodException 无此方法异常 SQLException 数据库异常 TimeoutException 超时异常 RuntimeException 运行时异常 |---- ArithmeticException 数学运算异常 |---- ClassCastException 类型转换异常 |---- IllegalArgumentException 无效参数异常 |---- IllegalStateException 无效状态异常 |---- NullPointerException 空指针异常 |---- IndexOutOfBoundsException 角标越界异常 |---- ArrayIndexOutOfBoundsException 数组角标越界异常 |---- StringIndexOutOfBoundsException 字符串角标越界异常
Throwable是java语言中所有错误或异常的超类,
Throwable 常用方法有:String getMessage() 返回此Throwable 的详细信息字符串。 void printStackTrace() 将此错误及其追踪打印出来。 String toString() 返回错误信息的简短描述。
而Exception中没有特有的方法,它从Throwable继承的常用方法有:
String getMessage(); //返回异常信息。 String toString(); //返回异常名称和异常信息。 void printStackTrace(); //打印异常名称、异常信息、异常位置。
举例:
try { int x=4/0; } catch { System.out.println(e.getMessage()); //获取异常信息。 System.out.println(e.toString()); //异常名称+异常信息。 e.printStackTrace(); //异常名称+异常信息+异常位置 //JVM默认的异常处理机制,就是在调用printStackTrace()方法,打印异常的堆栈跟踪信息。 } finally { System.out.println("over!"); }
throws:异常的声明。
如果功能在运行时有可能出现异常,就需要声明异常,或者抛出异常,否则编译失败。函数内如果抛出的是RuntimeException以及它的子类,函数上不用声明。因为一旦出现异常程序会直接停掉。
其他的都要在函数上声明throws。如果在函数内抛出RuntimeException异常,函数上不声明,编译一样通过。
如果在函数上声明了RuntimeException异常,调用者可以不用处理异常,编译一样通过。不需要声明的原因:
在运行时,出现了RuntimeException运行时异常,就是无法运算的情况,这时候希望程序停止。所以不需要调用者处理。自定义异常时,如果该异常发生后无法再继续运算,就让该自定义异常继承RuntimeException。
对多异常的处理。
(1)多个异常可以用多个catch()处理。
(2)异常抛出时,多个异常用逗号隔开。throws x1,x2
(3)程序如果有指定异常以外的异常,就该终止程序运行,即让JVM自动默认处理异常。举例:
class DivDemo { int div(int a,int b) throws ArithmeticException,ArrayIndexOutOfBoundsException { int [] arr=new int [a]; System.out.println(arr[4]); return a/b; } } class Demo { public static void main(String [] args) { DivDemo d=new DivDemo(); try { int x=d.div(4,0); System.out.println("x="+x); } catch (ArrayIndexOutOfBoundsException e) //第一个参数小于5时,这里就会捕捉此异常。 { System.out.println("角标越界异常:"+e.toString()); } catch (ArithmeticException e) //第二个参数为 0 时,这里就会捕捉此异常。 { System.out.println("运算方法异常:"+e.toString()); } System.out.println("over!"); } }
注意:
(1)声明了几个异常,就对应几个catch块,不要定义多余的catch块。
(2)多异常不会同时发生。第一个异常发生时,函数已经结束。
(3)多个catch()块如果有继承关系,父类的catch要放在最下面。自定义异常:
对于项目中出现的特有问题,可以按照java对问题封装的思想,进行自定义的异常封装。
函数中如果抛出自定义异常,就必须要给其定义处理动作。因为JVM中没有自定义异常的默认处理方式。自定义异常打印的结果中只有异常的名称,没有异常的信息。因为没有定义信息。
自定义异常必须是自定义类继承Exception,原因:
–异常体系有一个特点,异常类和异常对象都被抛出,都具有可抛性。
而可抛性是Throwable体系中独有的特点,只有这个体系中的类和对象才可以被throw和throws操作。throw和throws的区别:
throws使用在函数上,throw使用在函数内。
throws后面跟的是异常类,可以跟多个,用逗号隔开。
throw后跟的是异常对象。举例:
class FushuException extends Exception //自定义异常格式。 { FushuException(String message) { super(message); //自定义异常调用父类带参数构造函数。 } } class DivDemo { int div(int a,int b) throws FushuException //抛自定义异常。 { if (b<0) throw new FushuException("不能是负数"); //手动通过throw关键字抛出一个自定义异常对象。 return a/b; } } class Demo { public static void main(String [] args) { DivDemo d=new DivDemo(); try { int x=d.div(4,-1); //b=-1时,就开始处理FushuException异常了。 System.out.println("x="+x); } catch (FushuException e) { System.out.println(e.toString());//toString()包含getMessage()方法,返回的是传入的message的值。 } System.out.println("over!"); } }
子父类覆盖时的异常特点:
1.子类覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法只能抛出父类的异常或者该异常的子类。或者不抛。
2.如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。
3.如果父类或者接口的方法中没有异常抛出,子类在覆盖方法时发生异常,必须try处理,不可以抛出异常。异常的处理原则:
1.两种处理方式:try和throws。
2.定义到抛出异常的功能时,抛出几个,就处理几个。
3.多个catch时,父类的catch放到最下面。
4.catch内要定义针对性的处理方式。不是简单的printStackTrace和输出语句,也不要不写。
5.捕获的异常本功能处理不了时,可以继续抛出。相当于嵌套式异常格式。
4—Runtime
Runtime 对象类没有构造函数,说明不可以 new 对象。
–该类中大都是非静态方法,所以该类肯定提供了静态方法返回一个本类对象。
由此可以看出该类使用了单例设计模式。Runtime 常用方法:
static Runtime getRuntime() //调用静态方法返回一个Runtime对象。 Process exec(String cmd) //在单独的进程中执行指定的指令 long freeMemory() //返回虚拟机的空闲内存量。
举例:
class Demo { public static void main(String [] args) throws Exception { Runtime rt=Runtime.getRuntime(); //Runtime不可以 new 对象,只能这样写生成一个单例对象。 Process p=rt.exec("notepad.exe"); //exec()返回的是一个本机进程Process。 //也可以不加路径,系统会在当前目录下查找,还回去系统path环境变量里找。 Thread.sleep(4000); //线程等待4000毫秒。 p.destroy(); //销毁进程。 } }
5—System
System包含一些有用的类字段和常用方法。其中的方法和属性都是静态的。
它不能被实例化。常见方法:
System.in //标准输入流,一般用于获取键盘录入 System.out //标准输出流,用于输出信息 System.err //标准错误流,此输出流用于显示错误消息 void System.exit(); //终止java虚拟机。 void System.gc(); //运行垃圾回收器。 long System.currentTimeMillis(); //返回以毫秒为单位的当前时间。 Properties System.getProperties(); //确定当前系统属性。 static String System.getProperty(String key);
**说明:**Properties 是HashTable的子类,也就是Map集合的子类对象,可以通过Map的方法取出元素。
举例:
import java.util.*; class Demo { public static void main(String [] args) { Properties pro=System.getProperties(); for (Object oo : pro.keySet()) { String value = (String)pro.get(oo); System.out.println(oo+"::"+value); //可以通过Map的方法打印系统属性的键值和值。 } System.out.println(System.getProperty("os.name")); //打印系统名称 System.out.println(System.getProperty("user.country")); //国家名 System.out.println(System.getProperty("user.name")); //系统管理员名称 System.out.println(System.getProperty("user.language")); //用户语言 System.out.println(System.getProperty("haha")); //计算机中没有haha对应的键值信息,可以动态加载属性信息。 //运行时通过java -Dhaha=qqqqq Demo 的形式传递一个键值信息。 } }
6—Date & Calendar
Date表示特定的瞬间,精确到毫秒。
Date 表示的时间是1970 年 1 月 1 日 00:00:00 GMT(林威治标准时)到现在的毫秒数.
形式如:Tue May 12 21:26:31 CST 2015。import java.util.*; class Demo { public static void main(String [] args) { Date d=new Date(); System.out.println(d);//格式如:Tue May 12 21:26:31 CST 2015 } }
由于表示的不直观,所以需要用 SimpleDateFormat 对其进行格式化。
通过SimpleDateFormat 的构造函数 SimpleDateFormat(String s)
这里s表示一种模式,其中的元素有:yyyy : 2015 (年) yy : 15 (年) MM : 05 (月) MMM : 五月 dd: 16 (日) DD:年中的天数 E : 星期六 HH:时 mm:分 ss:秒 SSS : 毫秒数 z:时区-CST Z:时区-+0800 a:Am/Pm标记 w:年终的周数 W:月份中的周数 F:月份中的星期
如:表示公元2015年5月16日下午1点30分 东八区
表示为:"G yyyy.MM.dd E 'at' a HH:mm:ss z" //公元 2015.05.16 星期六 at 下午 13:30:00 CST "G yyyy年MMMdd日 E ,a HH时mm分ss秒 Z" //公元 2015年05月16日 星期六 , 下午 13时30分00秒 +0800
举例:
import java.util.*; //导入Date包。 import java.text.*; //导入SimpleDateFormat包。 class Demo { public static void main(String [] args) { Date d=new Date(); SimpleDateFormat f=new SimpleDateFormat("yyyy年MM月dd日"); //创建一个日期模式 String time=f.format(d); System.out.println(time); } }
Calendar
–如果想单独获取Date中的某个值,要用到 Calendar 类。
Calendar是一个抽象类,可以通过 getInstance 方法返回一个 Calendar 对象:Calendar now =Calendar.getInstance();
Calendar有很多字段,可以通过get方法获取字段。
ca.get(Calendar.YEAR); //返回日历中的年份 ca.get(Calendar.MONTH); //返回日历中的月份,0月表示实际中的1月份。 ca.get(Calendar.DAY_OF_MONTH);//返回月中的第几天 ca.get(Calendar.DAY_OF_WEEK); //返回一周中的第几天,第一天表示星期日。 ca.get(Calendar.HOUR_OF_DAY); //一天中的小时数 ca.get(Calendar.MINUTE); //多少分钟 ca.get(Calendar.SECOND); //多少秒
Calendar 中的常用方法:
void ca.add(field,amount); //给字段自增值 int ca.get(field); //获得字段值 String ca.toString(); //返回字符串表示形式 void ca.set(field,amount); //将给定字段设置为给定值 void ca.set(year,month,date); //设置年月日 TimeZone ca.getTimeZone(); //获得时区
举例:
import java.util.*; class Demo { public static void main(String [] args) { Calendar ca=Calendar.getInstance(); ca.set(2020,2,1); //设置指定年月日 System.out.println(ca.get(Calendar.YEAR)+"年"); System.out.println(ca.get(Calendar.MONTH)+1+"月"); System.out.println(ca.get(Calendar.DAY_OF_MONTH)+"日"); ca.add(Calendar.YEAR,2); ca.add(Calendar.MONTH,2); //时间是连续的,可以加减到上一年或下一年 ca.add(Calendar.DAY_OF_MONTH,-1); System.out.println(ca.get(Calendar.YEAR)+"年"); System.out.println(ca.get(Calendar.MONTH)+1+"月"); System.out.println(ca.get(Calendar.DAY_OF_MONTH)+"日"); } }
注意:求日历中的星期几,最好用查表法。
Calendar 在设置月份的时候,设置的1月,其实表示的是2月。
7—Math & Random
Math
它包含执行基本数学运算的方法。Math 中常见方法:
static T abs(n); //返回绝对值。n只可以是double,float,int,long。 static T max(n); //返回较大值。n只可以是double,float,int,long。 static T min(n); //返回较小值。n只可以是double,float,int,long。 static double random(); //返回随机值,介于0-1之间。包含头不包含尾。 static long round(double d); //返回d的四舍五入的long值。 static int round(float f); //返回f的四舍五入的int值。 static double ceil(double d); //返回大于d的最小的double值。ceil可以当做是天花板的意思。 static double floor(double d); //返回小于d的最大的double值。floor可以当做是地板的意思。 static double cbrt(double d); //返回d的立方根。 static double sqrt(double d); //返回d的平方根。 static double hypot(double x,y); //返回x和y的平方和的平方根。相当于求直角三角形的斜边。 static double pow(double x,y); //返回x的y次方的值。
举例:
class Demo { public static void main(String [] args) { double d1=Math.ceil(5.6); double d2=Math.ceil(5.4); long L=Math.round(5.6); System.out.println(d1); //d的进位 double值。小数位只要大于0.0,整数位就进1 。 System.out.println(d2); //d的舍位 double值。小数位不管是多少都舍弃。 System.out.println(L); //L的四舍五入值。 random(6,10); //用随机数生成10次骰子的点数。 random(10,10); //用随机数生成10次打靶命中分数。 random(100,10); //用随机数生成10个学生考试分数。 } public static void random(int n,int time) { for (int x=0;x<time;x++) { double d=Math.random(); //生成一个介于0-1的随机小数 int i=(int)(d*n+1); //小数转整数,整数范围在1-100之间。 System.out.println(i); } } }
Random :
此类用于生成随机数。
与 Math.random() 相比,它不如 Math.random() 易用。常用方法:
protected int next(int bits); //生成下一个随机数。 int nextInt(); //返回下一个随机整数。 int nextInt(int n); //返回取自0~(n-1) 的随机整数。
举例:
import java.util.*; class Demo { public static void main(String [] args) { Random rand=new Random(); for (int x=0;x<10;x++) { int n=rand.nextInt(10)+1; //nextInt(10)返回的数不包括10. System.out.print(n+" "); } } }
8—Scanner
Scanner是可以使用正则表达式来解析基本类型和字符串的简单文本扫描器。
构造方法:
Scanner(File res) 例:Scanner scan=new Scanner(new File("aaa.txt")); Scanner(InputStream res) 例:Scanner scan=new Scanner(System.in); Scanner(String res) 例:Scanner scan=new Scanner("aaa");
常用方法:
scan.nextBoolean(); scan.nextByte(); scan.nextDouble(); scan.nextFloat(); scan.nextInt(); scan.nextLong(); scan.nextShort(); Scanner.reset(); //重置此扫描器。返回Scanner。
举例:
import java.util.*; class Demo { public static void main(String [] args) { Scanner scan=new Scanner(System.in);//Scanner作为一个容器使用。 System.out.println("请输入一个数字:"); int x=scan.nextInt(); System.out.println("你输入的是:"+x); } }
9—BigInteger
有些运算数值超过 long 的范围,这时可以定义 BigInteger 对这样的数值进行存储并运算。
常用方法:
(1)字段:BigInteger.ONE; //BigInteger 类型,代表1 。 BigInteger.TEN; //BigInteger类型,代表10。 BigInteger.ZERO; //BigInteger 类型,代表0 。
(2)构造方法:
BigInteger(String s); //将s表示成BigInteger形式。
(3)方法:
BigInteger bi.abs(); //返回BigInteger的绝对值 BigInteger bi.add(BigInteger val); //返回 (bi + val) 的结果 BigInteger bi.and(BigInteger val); //返回 (bi & val) 的结果 BigInteger bi.divide(BigInteger val);//返回 (bi / val) 的结果 BigInteger bi.max(BigInteger val); //返回 bi 与 val 的最大值 BigInteger bi.min(BigInteger val); //返回 bi 与 val 的最小值 BigInteger bi.mod(BigInteger val); //返回 (bi % val) 的结果 BigInteger bi.multiply(BigInteger val); //返回 (bi * val) 的结果 static BigInteger BigInteger.valueOf(long L); //long型值转成BigInteger型 int bi.compareTo(BigInteger val); //bi大于val,返回1,小于返回-1,等于返回0 。 int bi.intValue(); //将BigInteger转成int型 String bi.toString(); //BigInteger的字符串表示形式
举例:
import java.math.BigInteger; class Demo { public static void main(String [] args) { BigInteger bi=BigInteger.ONE; //BigInteger.ONE 代表BigInteger类型的 1 。 for (int x=2;x<=100;x++) { bi=bi.multiply(BigInteger.valueOf(x)); //两BigInteger相乘。 } System.out.println(bi); System.out.println(bi.mod(BigInteger.TEN)); //打印 bi 模10 的结果。 } }
10—单例设计模式
优点: 在内存中只有一个对象,节省内存空间。
也可以避免频繁地创建和销毁对象,避免对共享资源的多重占用,提高了性能。
可以全局访问。
单例设计模式有两种:
(1)饿汉式:先初始化对象。class demo { private demo(){} private static demo x=new demo(); public static demo getInstance() { return x; } }
(2)懒汉式:方法被调用时才初始化(延时加载)。
class demo { private static demo x=null; private demo(){}; public static demo getInstance() { if (x==null) { synchronized(demo.class) { if (x==null) x=new demo(); } } } }
注意:定义单例时,一般使用饿汉式。因为它安全。
11—模板方法设计模式
定义功能时,功能的一部分是确定的。确定的部分在使用不确定的部分。将不确定的部分由子类复写。
举例:一段获取程序运行时间的代码。
class GetTime { public void getTime() { long start=System.currentTimeMillis(); //返回一个long值,代表1970Y 1M 1D 开始至今的毫秒数。 for (int x=0;x<1000;x++) //for语句部分的运行左右着时间的多少。不同程序不同运行时间。要想获取其他程序的时间就改这部分。 { System.out.print(x+" "); } long end=System.currentTimeMillis(); System.out.println("TIME:"+(end-start)); //程序开始和结束的时间相减,可以获取程序运行的时间。 } } class Demo8 { public static void main(String [] args) { GetTime gt=new GetTime(); gt.getTime(); } }
该例可以获取一段程序的运行时间,只要替换需要求运行时间的程序,就可以求其他程序的运行时间。
如果把这段固定的程序封装成模板,就可以解决一类问题。
这就是模板方法设计模式。模板的代码抽取:
abstract class GetTime //模板,不能实例化。
{
public final void getTime() //加final修饰,防止子类把特有定义复写。
{
long start=System.currentTimeMillis();
run();
long end=System.currentTimeMillis();
System.out.println("TIME:"+(end-start));
}
public abstract void run(); //模板中,这一块不一定是抽象的。
}
class GTime extends GetTime //套用模板
{
public void run() //复写抽象类中的run方法,
{
for (int x=0;x<199;x++)
{
System.out.print("x="+x+" ");
}
}
}
class Demo
{
public static void main(String [] args)
{
GTime ti=new GTime();
ti.getTime();
}
}