*面向对象**
对象转换
假如我们定义一个父类Animal、一个子类Dog和一个子类cat
public class Animal{//父类
}
class Dog extends Animal{//定义一个子类
public void wang(){
System.out.println("狗崽汪汪叫");
}
}
class Cat extends Animal{//定义一个子类
public void miao(){
system.out.println("小猫崽喵喵叫");
}
}
//调用
public class test{
public static void mian(){
Animal a= new Dog();//向上类型转换
a.wang();//错误,编译器只认为a是Animal类型对象,需强转为Dog类型对象才能调用
Dog d=(Dog) a;//强制类型转换,向下类型转换
d.wang();//调用成功
Cat c=(Cat) a;//编译通过,但是编译器认为a是Dog类型对象,不能强制转换
c.miao();//调用不成功
}
}
抽象类和抽象方法
.抽象方法
使用abstract修饰的方法,没有方法体,只有声明,定义的是一种‘规范’,就是告诉子类必须要给抽象方法具体的实现。
.抽象类
包含抽象方法的类就是抽象类,**抽象类只能用来继承**。通过Abstract方法定义规范,然后**要求子类必须定义具体的实现**,通过抽象类,我们可以做到严格限制子类的设计,以便子类之间更加通用。
abstract class Animal{//定义一个抽象类
abstract public void shout();//定义一个抽象方法
}
class Dog extends Animal{
//子类必须实现父类的抽象方法,否则编译错误
public void shout(){//实现抽象方法
system.out.println("汪汪汪");
}
public void seeDoor(){
system.out.println("看门中---");
}
}
接口interface
和抽象类的区别
比抽象类还抽象,抽象类里面还可以有一些具体实现了的方法,但是接口里面全是抽象方法对子类有了更加的规范的约束。
interface Volant{//飞行接口
int fly_hight=100;//总是public static final 类型的
void fly();//总是public abstract void fly()类型的
}
interface Honest{//善良接口
void helpOther();
}
/*
*Angel类实现飞行和善良接口
*/
public class Angel implements Volant,Honest{
public void fly(){
system.out .println("我飞起来了");
}
public void helpOther(){
system.out.println(”扶老奶奶过马路“);
}
}
总结:
普通类:具体的实现
抽象类: 具体实现,规范(抽象方法)
接口:规范!
接口中定义静态方法和默认方法
默认方法
JAVA8之后,允许在接口中定义默认方法和类方法了。
默认方法和抽象方法的区别:抽象方法必须要实现,默认方法不是。这个接口的实现类都可以通过继承得到这个方法。
默认方法需使用到default关键字。
interface A{
default void shout(){
system.out.println("汪汪汪");
}
}
class Test_A implements A{
public void shout(){
System.out.println("顶你个肺");
}
}
静态方法
静态方法直接从属于接口(接口也是一种类,一种特殊的类),可以通过接口名调用。如果子类中定义了相同名字的静态方法,那就是两个完全不同的方法了,直接从属于子类。可以通过子类名调用。
接口的多继承
接口完全支持多继承,和类的继承类似,子接口拓展某个父接口,将会获得父接口中定义的一切。
String类
字符串相等判断---常量池原理
String str1=new String ("abcdefg");
String str2="abcdefg";
System.out.println(str1==str2);//返回false,这个是判断str是否和str2相等
//涉及到字符串比较的时候都用equals()方法
System.out.println(str1.equals(str2));//返回的是true,这个是判断str1里面的值是否和str2里面的值相等
-
String类的常用方法列表
方法 解释说明 char charAt(int index) 返回字符串中第index个字符 boolean equals(String other) 两个字符串的值相等返回true;否则返回false boolean equalsIgnoreCase(String other) 两个字符串的值相等(忽略大小写)返回true;否则返回false int indexOf(String str) 返回从头开始查找第一个字符串str在字符串中的位置,未找到返回-1 lastIndexOf(String str) 返回从结尾开始查找第一个字符串str在字符串中的位置,未找到返回-1 int length() 返回字符串的长度 String replace(char oldChar, char newChar) 返回一个新字符串,它是新串替换字符串里面的所有oldChar生成的 boolean startsWith(String prefix) 如果字符串以prefix开头,则返回true boolean endsWith(String prefix) 如果字符串以prefixji结尾,则返回true String substring(int beginIndex) 返回一个字符串,该串包含从原始字符串的beginIndex位置开始到串尾 String substring(int beginIndex,int endIndex) 返回一个从beginIndex位置到(endIndex-1)位置的所有字符 String toLowerCase() 返回一个新字符串,原始字符串大写变小写 String toUpperCase() 返回一个新字符串,原始字符串字符小写变大写 String trim() 返回一个新字符串,该串删除了原始字符串头部和尾部的空格
内部类
内部类是一类特殊的类, 指的是一个定义在一个类的内部的类,在实际开发中,为了方便使用外部类的相关属性和方法,这时候我们通常会定义一个内部类。
-
内部类的作用
内部类提供了更好的封装,只能让外部类使用,直接访问,不允许同一个包中的其他类直接访问,
内部类可以直接访问外部类的私有属性,内部类被当成外部类的成员,但外部类不能访问内部类的内部属性。
public class Outer{//外部类
private int age=10;
private void show(){
System.out.println("要你好看");
}
//内部类
public class Inner{
private String name="谢洪凯";
private int age=20;
private void shows(){
System.out.println("Inner.shows");
System.out.println(age);
System.out.println(Outer.this.age);//当外部类和内部类发生重名时可以通过Outer.this.成员名来调用
show();//内部类可以直接使用外部类的成员
}
}
public static void main(){
outer.Inner A=new outer().new Inner();//定义内部类的对象的方式
A.shows();//调用内部类方法
//另一种写法
Outer.outer=new Outer();
Inner.inner=outer.new Inner();
inner.shows();
}
}
内部类分类:
-
1.成员内部类
-
非静态内部类
-
静态内部类
-
-
2.匿名内部类
-
3.局部内部类
非静态内部类:
非静态内部类(外部类使用非静态内部类和平时使用其他类没有什么不同)
-
非静态内部类必须寄存在一个外部类对象里面,因此如果存在一个非静态内部类对象,那么一定存在一个对应的外部类对象,非静态内部类对象单独属于外部类的某个对象;
-
非静态内部类可以直接访问外部类的成员,但是外部类不能直接访问非静态内部类成员;
-
非静态内部类不能有静态方法,静态属性和静态初始化块。
静态内部类:
定义方式:
static class ClassName{
//类体
}
使用要点:
-
1、静态内部类可以访问外部类的静态成员,不能访问外部内的普通成员;
-
2、静态内部类看作外部类的一个静态成员。
匿名内部类:
适合那种只需要使用一次的类,比如键盘监听操作等等,在安卓开发、awt、swing、开发中常见。
语法:
new 父类构造器(实参类表)\实现接口 (){
//匿名内部类类体!
}
eg:
public class TestInnerClass{
public void Test(A a){
a.run();
}
public static void main(){
TestInnerClass T=new TestInnerClass();
T.Test(new AA());
T.Test(new A(){//新建一个匿名类,用完之后就没了
@Override
public void run(){
System.out.println("你好S啊");
}
});
T.Test(new A(){//再新建一个匿名类
@Override
public void run(){
System.out.println("对不起!你不S");
}
});
}
}
class AA implements A{
public void run(){
System.out.println("你是真的S");
}
}
public interface A{
void run();
}
局部内部类:
定义在方法内部的,作用域只限于本方法,称为局部内部类。
数组
数组的定义:
数组是相同类型数据的有序集合。
-
长度是确定的,数组一旦被创建,它的大小是不可以被改变的;
-
其元素的类型必须是相同的类型,不允许出现混合型;
-
数组类型可以是任何数据类型,包括基本类型和引用类型;
-
数组变量属于引用类型,数组也是对象。
老鸟的建议:数组中的每个元素相当于该对象的成员变量。数组本身就是对象,JAVA中对象是堆中的,因此·数组无论是保存原始类型还是其他对象类型,数组对象本身是在堆中存储的。
public class Test { public static void main(String[] args) {
int[] S=null;//声明一个数组
S=new int[10];//给数组分配空间
for(int i=0;i<10;i++){
S[i]=2*i+1;//给数组元素赋值,数组也是对象,数组中的元素就是对象的属性
System.out.println(S[i]);
}
}
数组的默认初始化
int array[]=new int[2];//默认值:0 ,0
boolean[] b=new boolean[2];//默认值:false,false
String[] str=new String[2];//默认值:null,null
数组的动态初始化
int array[]=new int[2];
array[0]=1;
array[1]=2;
数组的静态初始化
int array[]={1,2,3};//静态初始化基本类型数组;
Man[] mans={new Man(1,2),new Man(1,4)};//静态初始化引用类型数组
数组的遍历方法
-
for循环
int[] a={1,2,3,4,5,6,7,8,9} for( int i=0;i<a.length;i++){ System.out.println(a[i]); }
-
for-each循环
String[] ss={"aaa","bbb","ccc","ddd"}; for(String temp:ss){ System.out.println(temp); }
注意事项:
-
for-each增强for循环在遍历数组过程中不能修改数组中某元素的值;
-
for-each仅适用于数组的遍历,不涉及有关索引、下标的操作。
-
数组的拷贝
System类里也包含了一个static void arraycopy(object src,int srcpos,object dest,int destpos,int length)方法,该方法可以将src数组里的元素值赋给dest数组的元素其中srcpos指定从src数组的第几个元素开始赋值,length指定将src数组的多少个元素赋给dest数组的元素。
public class Test {
public static void main(String[] args) {
String[] strings={"阿里","尚学堂","京东","搜狐","网易"};
String[] sBak=new String[6];
System.arraycopy(strings,0, sBak,0, strings.length);
for(int i=0;i<sBak.length;i++){
System.out.print(sBak[i]+'\t');
}
}
}
Java.util.Arrays类
该类包含了常用的数组操作,方便我们的日常开发,Arrays类包含了排序,查找,填充,打印内容 等常见的操作。
使用Arrays对数组元素打印
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] a={1,2};
System.out.println(a);//打印数组引用的值
System.out.println(Arrays.toString(a));//打印数组元素的值
}
}
使用Arrays对数组元素进行排序
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] a={1,3,2,4,5,9,7,8,6};
System.out.println(Arrays.toString(a));
Arrays.sort(a);
System.out.println(Arrays.toString(a));
}
}
使用Arrays实现二分法查找
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] a={1,3,2,4,5,9,7,8,6};
System.out.println(Arrays.toString(a));
Arrays.sort(a);//使用二分法查找,必须先排序
System.out.println(Arrays.toString(a));
//返回排序后新的索引位置,若未找到返回负数
System.out.println("该元素的索引:"+Arrays.binarySearch(a, 5));
}
}
使用Arrays类对数组进行填充
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int a[]={11,12,23,43,545,656};
System.out.println(Arrays.toString(a));
Arrays.fill(a, 2,4,100);//填充,将2到4索引的元素替换为100
System.out.println(Arrays.toString(a));
}
}
多维数组
什么是多维数组:
简单点来说就是数组里面的元素还是数组。
二维数组
public class Test {
public static void main(String[] args) {
int[][] a={
{1,2},{1,12,3},{1,23,4,5}};
System.out.println(a[2][3]);
}
}
如何获取二维数组的长度
//获取二维数组中第一维数组的长度
System.out.println(a.length);
//获取二维数组中第二维数组中第一个数组的长度
System.put.println(a[0].length);
Object数组存取表格数据
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
Object[] a1={"001","x1","12010"};//定义一维数组,里面填充表里面的数据
Object[] a2={"002","x2","10211"};//定义一维数组,里面填充表里面的数据
Object[] a3={"003","x3","12011"};//定义一维数组,里面填充表里面的数据
Object[][] emps=new Object[3][];//定义一个Obiect二维数组
emps[0]=a1;//把上面填充好了的一维数组数据赋给该二维数组的第二维数组里面
emps[1]=a2;
emps[2]=a3;
System.out.println(Arrays.toString(emps[0]));
System.out.println(Arrays.toString(emps[1]));
System.out.println(Arrays.toString(emps[2]));
}
}
使用javabean和一维数组保存表格信息
import java.util.Arrays;
/*
*使用javabean和一维数组来存取表格信息
*/
public class Test {
public static void main(String[] args) {
Emp emp0=new Emp(0101,"高小一",18,"程序员","2019-10-1");
Emp emp1=new Emp(0102,"高小二",19,"程序员","2019-10-2");
Emp emp2=new Emp(0103,"高小三",20,"程序员","2019-10-3");
Emp[] emps=new Emp[3];
emps[0]=emp0;
emps[1]=emp1;
emps[2]=emp2;
for(int i=0;i<emps.length;i++){
System.out.println(emps[i].toString());
}
}
}
class Emp{
private int id;
private String name;
private int age;
private String job;
private String hiredate;
public Emp(){};
public Emp(int id,String name,int age,String job,String hiredate){
this.id=id;
this.name=name;
this.age=age;
this.job=job;
this.hiredate=hiredate;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public String getHiredate() {
return hiredate;
}
public void setHiredate(String hiredate) {
this.hiredate = hiredate;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "["+id+"\t"+name+"\t"+age+"\t"+job+"\t"+hiredate+"]";
}
}
Comparable接口
该接口中只有一个方法comparaTo(),这个方法定义了对象之间的比较规则,依据这个比较规则,我们就能实现对象的排序。
事实上,java中排序算法也依赖Comparable接口。
Comparable接口中只有一个算法:(大于返回1,等于返回0,小于返回-1)
public int comparaTo(Object obj)//obj为要比较的对象
常见算法
冒泡排序算法
如果大家想详细的理解算法的话,去这个网站:VisuAlgo - visualising data structures and algorithms through animation
int temp,i;
for(i=0;i<values.length;i++){
boolean flag=true;
for(int j=0;i<values.length-1-i;j++){
if(values[j]>values[j+1]){
temp=values[j];
values[j]=values[j+1];
values[j+1]=temp;
flag=false;
}
}
}
二分法查找
二分法检索(binary search),又称折半检索。二分法的基本思想是设数组中的元素从小到大排列存放在数组Array中,首先将给定值key与数组中间位置上的元素的关键码key比较,如果相等,则检索成功。
否则,若key小,则在前半部分中继续二分检索。
若key大,则在数组后半部分中继续二分检索。这样,经过一次检索就缩小一半的检索空间,如此进行下去,直到检索成功或检索失败。
//二分法基本代码
public static void BinarySearch(int array[],int value){//要查找的数组和要查找的值
int low=0;
int high=array.length-1;
while(low<=high){
middle=(high-low)/2;
if(value==array[middle]){
return middle;//找到了返回查找数的索引
}
if(value<array[middle]){
high=middle-1;
}
if(value>array[middle]){
low=middle+1;
}
}
return -1;//未找到返回-1
}
常用类
1.基本数据类型的包装类
(1)final class:子类不能被继承或者说没有子类。
(2)所有“数字型”包装类与Number之间的继承关系,Number类是一个抽象类。
(3)Number是一个抽象类,因此它的所有抽象方法都需要提供实现。Number类提供了抽象方法intValue()、longValue()、floatValue()、doubleValue()四种方法,意味着所有的“数字型”包装类都可以相互转型。
public class Test {
public void TestInteger(){//基本数据类型转为对象
Integer integer=new Integer(300);
Integer integer2=integer.valueOf(200);
System.out.println(integer+integer2);
//包装类类对象转为基本数据类型
double d=integer2.doubleValue();
System.out.println(d);
//字符串转为Integer对象
Integer integer3=integer.parseInt("4000");
System.out.println(integer3);
Integer integer4=new Integer("500");
//Integer对象转为字符串
String str=integer3.toString();
//一些常见int类型相关的常量
System.out.println("int能表示的最大整数:"+integer.MAX_VALUE);
}
public static void main(String[] args) {
Test test=new Test();
test.TestInteger();
}
}
(4)包装类的基础知识
Java是面向对象的语言,但不是纯面向对象,以为我们经常用到的基本数据类型就不是对象,但是在实际运用中,我们经常需要将基本数据转化为对象,以便于操作,比如:将基本数据类型存储到Object[]数据或集合中的操作等等。
基本数据类型 | 包装类 |
---|---|
byte | Byte |
boolean | Boolean |
short | Short |
char | Character |
int | Integer |
long | Long |
float | Float |
double | Double |
(5)在以后的编程中,我们会频繁的用到基本数据类型和包装类对象之间的转换。
比如当我们想把一个数字转为一个字符串的话,下面这段代码中的i不是一个对象,因而会报错,需把i转为一个对象之后才能被转为字符串。
//转为对象之前
public class Test {
public void TestInteger(){
int i=300;
String string=i.toString();//报错,因为i不是一个对象
System.out.println(string);
}
public static void main(String[] args) {
Test test=new Test();
test.TestInteger();
}
}
//转为对象之后
public class Test {
public void TestInteger(){
int i=300;
Integer integer=Integer.valueOf(i);//将i转为Integer类对象
String string=integer.toString();
System.out.println(string);
}
public static void main(String[] args) {
Test test=new Test();
test.TestInteger();
}
}
(6)总结,我们的包装类可以干甚:
包装类可以把基本数据类型,包装类对象还有我们的字符串,这三个之间来回转化,包装类对象起核心的作用,把数据和字符串来回转。比如想把一个字符串转为一个数据,需先把字符串喜欢为对象,才能转为数据。
2.自动装箱和自动拆箱
自动装箱
基本类型的数据处于需要对象的环境时,会自动转为对象。
以Integer为例:
在JDK5之前,Integer i=5这样的代码是错误的,必须通过Integer i=new Integer(5)这样的语句来实现基本数据类型转为包装类的过程。在之后,JAVA提供了自动装箱的功能,因此只Integer i=5这样的语句就能事项其间的转化。这是因为JVM为我们执行了Integer i=Integer.valueOf(5)这样的操作,这就是java的自动装箱。
自动拆箱
每当需要一个值时,对象会自动转为基本数据类型的包装类,没必要再去调用转型方法,如:Integer i=5;int j = i;这样的过程就是自动拆箱。
包装类空指针异常报错
public class Test {
public void TestInteger(){
Integer i=null;//i是空,不能调用其方法
int j=i;//编译器帮你改成i.intvalue();但是i为空,不能调用方法
}
public static void main(String[] args) {
Test test=new Test();
test.TestInteger();
}
}
3.包装类的缓存问题
public class Test {
public void TestInteger(){
Integer a=3000;
Integer b=3000;
//如果数字在[-128,127]之间的时候,返回的是缓存数组中的某个元素
Integer c=123;
Integer d=123;
System.out.println(a==b);//两个不同的对象,返回false
System.out.println(c==d);//因为c,d对象返回的都是同一个数组(缓存数组)中的元素,所以返回true
System.out.println(a.equals(b));//返回true
}
public static void main(String[] args) {
Test test=new Test();
test.TestInteger();
}
}
4.自定义一个包装类
package MyInteger;
import java.lang.management.MemoryUsage;
public class MyInteger {
public static final int low=-128;
public static final int high=127;
private int value;
private static MyInteger[] cache=new MyInteger[256];
static{//静态初始化
//[-128,127]缓存进来
for(int i=low;i<high;i++){
//-128->0,-127->1,-126->2
cache[i+128]=new MyInteger(i);
}
}
private static MyInteger valueOf(int i) {
if(i>=low&&i<=high){
return cache[i+128];
}
return new MyInteger(i);
}
private MyInteger(int i) {
this.value=i;
}
@Override public String toString() {
// TODO Auto-generated method stub
return this.value+"";
}
public static void main(String[] args) {
MyInteger myInteger=MyInteger.valueOf(300);
System.out.println(myInteger);
}
}
5.字符串相关类
String类、StringBuilder类、StringBuffer类是三个字符串相关类。String类是对象代表不可变的字符序列,StringBuilder类和StringBuffer类代表可变字符序列。关于这三种类详细的用法,笔试的时候会用到,必须掌握好。
StringBuilder类和StringBuffer类的区别(二者均是抽象类AbstractStringBuilder的子类):
-
StringBuffer 线程安全,做线程同步检查,效率很低。
-
StringBuilder 线程不安全,不做线程同步检查,因此效率高,建议采用该类。
常用方法列表:
方法 | 属性 |
---|---|
重载的public StringBuilder append(...)方法 | 可以为StringBuilder 对象添加字符序列,仍然返回自身对象 |
public StringBuilder delete(int start,int end) | 删除从start到end-1的一段字符序列,仍然返回自身对象 |
public StringBuilder deleteCharAt(int index) | 移除指定位置上的char,仍然返回自身对象 |
重载的public StringBuider insert(...) | 为StringBuilder对象在指定位置插入字符序列,仍然返回自身对象 |
public StringBuilder reverse() | 用于将字符序列逆序,仍然返回自身对象 |
public String toString() | 返回此字符序列中数据的字符串表示形式 |
和String类含义类似的方法
方法 | 属性 |
---|---|
public indexOf(String str) | 返回该字符串的位置,没有返回-1 |
public int indexOf(String str,int fromIndex) | 返回从fromIndex开始查找字符串str的位置,没有返回-1 |
public String subString(int start) | 返回从start位置开始到最后一个字符的字符串 |
public String subString(int start,int end) | 返回一个从start位置到(end-1)位置的所有字符 |
public int length() | 返回字符串的长度 |
char charAt(int index) | 返回字符串中第index个字符 |
注意它的上面几种方法返回的都是自身对象(return this)
例如append()方法
package MyInteger;
import java.lang.management.MemoryUsage;
public class MyInteger {
public static void main(String[] args) {
String str1="abcd";//不可变字符序列
StringBuffer sb2=null;//可变字符序列,线程安全,效率低
StringBuilder sb3=null;//可变字符序列,线程不安全,效率高
sb2=new StringBuffer("gao");
sb2.append(123);
sb2.append(456);
System.out.println(sb2);
//还可以这样写
sb2.append("aa").append("bb").append("cc");
System.out.println(sb2);
}
}
不可变和可变字符序列使用陷阱
-
String使用陷阱
String已经初始化就不能再改变其内容了。对String字符的操作实际上是对其副本的操作,原来的字符串一点都没有改变,比如:创建一个字符串String str="abc";str=str+"defg";实际上原来的字符串abc已经丢弃了现在又产生一个新的字符串,如果多次执行改变字符串内容的操作,会导致大量副本字符串留在内存中,效率降低如果这种操作放在循环当中,会严重影响时间和空间的性能。甚至会导致服务器的崩溃。
package MyInteger
import java.lang.management.MemoryUsage;
public class MyInteger {
public static void main(String[] args) {
//使用String类
System.out.println("string类");
String str=null;
long time=Runtime.getRuntime().freeMemory();//获取当前系统剩余内存空间
System.out.println(time);
long time2=System.currentTimeMillis();//获取系统的当前时间
System.out.println(time2);
for(int i=0;i<10000;i++){
str=str+i;
}
long time3=Runtime.getRuntime().freeMemory();
System.out.println(time3);
long time4=System.currentTimeMillis();
System.out.println(time4);
System.out.println("运行之后占用了"+(time3-time)+"的内存空间");
System.out.println("运行了"+(time4-time2)+"秒");
System.out.println();
//使用StringBuffer类
System.out.println("stringBuffer类");
StringBuffer str1=new StringBuffer("");
long num=Runtime.getRuntime().freeMemory();//获取当前系统剩余内存空间
System.out.println(num);
long t=System.currentTimeMillis();//获取系统的当前时间
System.out.println(t);
for(int i=0;i<10000;i++){
str1.append(i);
}
long num2=Runtime.getRuntime().freeMemory();
System.out.println(num2);
long t2=System.currentTimeMillis();
System.out.println(t2);
System.out.println("运行之后占用了"+(num-num2)+"的内存空间");
System.out.println("运行了"+(t2-t)+"秒");
}
}
开发中容易造成内存泄漏的操作
-
创建大量无用对象
String str=null; for(int i=0;i<10000;i++){ str=str+i;//相当于产生了10000个String对象 }
-
静态集合类的使用
像HashMap、Vector、List等的使用最容易出现内存泄露,这些静态的生命周期和应用程序一致,所有的对象Object也不能释放。
-
各种连接对象(IO流对象,数据库连接对象,网络连接对象)未关闭,其属物理连接,需关闭。
-
监听器的使用
释放对象时,没有删除相应的监听器
6.时间处理相关类
“时间如流水,一去不复返”,在计算机世界,我们把1970年1月1日00:00:00定位基准时间,每个度量单位是毫秒(1秒的千分之一)。
如果想获得现在是可的时刻数值,可以使用Long time=System.currentTimeMillis();
时间日期相关类:
Date时间类(java.util.Date)
package MyInteger;
import java.util.Date;
import javax.xml.crypto.Data;
public class MyInteger {
public static void main(String[] args) {
Date d1=new Date(1000L*3600*24*365*250);//传参代表1970年1月1号加上括号里面的时间
System.out.println(d1);
Date d2=new Date();//不传参则代表当前时间
System.out.println(d2);
System.out.println(d2.getTime());
}
}
方法 | 属性 |
---|---|
Date() | 分配一个Date对象,并初始化此对象为系统当前的日期和时间,可以精确到毫秒 |
Date(long date) | 分配Date对象并初始化此对象,以表示自从标准基准时间(称为“历元”,即1970年1月1日00:00:00 GMT)以来指定毫秒数 |
boolean after(Date when) | 测定此日期是否在指定日期之后 |
boolean before(Date when) | 测定此日期是否在指定日期之前 |
boolean equals(Object obj) | 比较两个日期的相等性 |
long getTime() | 返回1970年以来date对象表示的毫秒数 |
String toString() | 把此Date对象转换成以下形式的String: |
dow mon dd hh:mm:ss:zzz yyyy 其中dow表示一周中的某一天 |
DateFormat类SimpleDateFormat类
-
DateFormat类的作用
把时间对象转化为指定格式的字符串,反之,把指定的字符串转化为时间对象。
它是一个抽象类,一般使用他的子类SimpleDateFormat来实现。
package MyInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;/* * 测试时间对象和和字符串的相互转化 * 使用DateFormat * 和SimpleDateFormat */
import java.util.Date;
public class MyInteger {
public static void main(String[] args) throws ParseException {
SimpleDateFormat df=new SimpleDateFormat("YYYY-MM-dd hh:mm:ss");//将字符串转化为Date类对象
Date d1= df.parse("1970-1-1 10:44:22");
System.out.println(d1.getTime());
//将Date对象转为字符串
Date d2=new Date();
String str=df.format(d2);
System.out.println(str);
}
}
CheckedException 已检查异常
所有不是RuntimeException的异常,都统称为已检查异常。如IOException、SQLException等以及用户自定义的Exception异常这类异常在编译时是就必须做出处理,否则无法通过编译。
异常的处理方式有"try/catch"捕获异常、使用"throws"声明异常。
日历Calendar类
-
Calendar类是一个抽象类,为我们提供了日期计算的相关功能,比如年、月、日、时、分、秒的展示和计算。
-
GregorianCalendar是Calendar的一个具体子类,提供了世界上大多数国家的/地区的使用的标准日历系统。
-
菜鸟雷区