《Java学习笔记1》

*面向对象**

对象转换

假如我们定义一个父类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的一个具体子类,提供了世界上大多数国家的/地区的使用的标准日历系统。

  • 菜鸟雷区

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值