Fork me on GitHub

JavaSE Day13 时间API 内部类


时间日期

java.util.Date

java.util.Date是父类,它还有三个子类分别是:

方法

// 获取当前时间
java.util.Date date = new java.util.Date();
System.out.println(date); // 英文格式时间;
// 单位全是毫秒数
System.out.println(date.getTime());
// 获取long格式的时间 毫秒数
System.out.println(System.currentTimeMillis());
// long格式的时间 毫秒数
java.util.Date date1 = new java.util.Date(1537320606539L);
// 将long格式的数据,转换为英文格式的时间
System.out.println(date1);

子类

java.sql.Date

Date d1 = new Date(date.getTime());// 更具long格式的数据,获得日期
// 日期转字符串
String sd1 = d1.toString();//日期
System.out.println(sd1);
// 字符串 转 日期
d1 = Date.valueOf(sd1);
System.out.println(d1);

java.sql.Time

Time t1 = new Time(date.getTime());
String str1 = t1.toString();
t1 = Time.valueOf(str1);

java.sql.Timestamp

Timestamp tp1 = new Timestamp(date.getTime());
System.out.println(tp1)

格式化

java.text.SimpleDateFormat

SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
System.out.println(sdf1.format(date));//将英文格式的时间,转换为定义好的格式

日历

是一个抽象类

Calendar c = Calendar.getInstance();
    获得一个实例
// 日历表示的当前系统时间
    System.out.println(c.getTime());
// 获得年月日
    System.out.println(c.get(Calendar.YEAR));
    System.out.println(c.get(Calendar.MONTH));
    System.out.println(c.get(Calendar.DATE));
// 10年前的时间
    c.add(Calendar.YEAR, -10);
// 10年后的时间
    c.add(Calendar.YEAR, 10);
// 设置一个时间
    Calendar c1 = Calendar.getInstance();
c1.set(2012, 4, 6);// 月份 要-1
Calendar c2 = Calendar.getInstance();
c2.set(2016, 6, 8);
 //    月份是从0开始的;
 // 一个日期,是否 在参数日期前,是->true
    System.out.println(c1.before(c2));

java8.0中的日期时间类

LocalDate

// 当前时间
    LocalDate ldate1 = LocalDate.now();
// 设置时间
    ldate1 = LocalDate.of(2018, 5,29);
// 获取时间
    System.out.println(ldate1.getYear());
    System.out.println(ldate1.getMonthValue());
    System.out.println(ldate1.getDayOfMonth());// 一个月中第几天
    System.out.println(ldate1.getDayOfYear());// 一年中的第几天
    System.out.println(ldate1.getDayOfWeek());// 星期几
// 当前时间前
    System.out.println(ldate1.minusYears(10));// 10年前
    System.out.println(ldate1.minusMonths(10));// 10月前
    System.out.println(ldate1.minusDays(10));// 10天前
// 当前时间后
    System.out.println(ldate1.plusYears(10));// 10年后
    System.out.println(ldate1.plusMonths(10));// 10月后
    System.out.println(ldate1.plusDays(10));// 10天后

LocalTime

// 基本操作
    LocalTime ltime1 = LocalTime.now();
    ltime1 = LocalTime.of(9, 2, 34);
    System.out.println(ltime1);
// 秒操作
     System.out.println(ltime1.getSecond());
// 小时操作
    System.out.println(ltime1.plusHours(20));
    System.out.println(ltime1.minusHours(20));

LocalDateTime

// 基本操作
    LocalDateTime ldt = LocalDateTime.now();
    ldt = LocalDateTime.of(1991,12,23,12,5,5);
    System.out.println(ldt);

Duration(时间计算类)

必须使用localDateTime类参数

    LocalDateTime ldt1 = LocalDateTime.of(2012,2,12,5,56,56);
    LocalDateTime ldt2 = LocalDateTime.of(2013,2,12,4,56,34);
    Duration d = Duration.between(ldt1,ldt2);
    System.out.println(d.toDays());
// 毫秒/1000/60/60/24 = 天数

内部类

顶级类

  • 成员内部类
    • 实例成员内部类
    • 静态成员内部类
  • 局部内部类
  • 匿名内部类

成员内部类

实例成员内部类

可以使用四种访问修饰符

访问

  1. 外部类通过内部类的对象,访问内部类数据
  2. 内部类直接访问外部类成员,省略了外部类对象(外部类.this.)
package day13;

class Cat {
    private double weight;

    public Cat(double weight) {
        this.weight = weight;
    }

    // 内部类
    class CatBody {
        String color;

        public CatBody(String color) {
            this.color = color;
        }

        public void show() {
            // 内部类中,可以直接访问外部类成员,省略了外部类对象Cat.this
            // 每个内部类对象中都封装了一个外部类对象
            System.out.println("小猫的颜色是:" + color + "," + Cat.this.weight);
        }
    }

    public void display() {
        System.out.println("小猫的重量:" + weight);
        // 调用内部类中的方法 ,创建对象调用
        CatBody body = new CatBody("白色");
        body.show();
    }


}

public class TestCatInner {
    public static void main(String[] args) {
        Cat xiaohua = new Cat(22.2);
        xiaohua.display();
        // 独立使用内部类对象
        Cat.CatBody body = xiaohua.new CatBody("黑色");
        body.show();

        // 匿名写法
        Cat.CatBody body1 = new Cat(11.1).new CatBody("灰色");
        body1.show();
    }
}

实例内部类属于 外部类的对象

独立使用

// 利用外部类对象创建
    Cat xiaohua = new Cat("xx");
    Cat.CatBody body=xiaohua.new CatBody("黑色");
// 利用匿名外部类创建
    Cat.CatBody body = new Cat(“xx”).new CatBody("黑色")

字节码文件

 文件名 外部类$内部类.class

注意

  1. 实例内部类不允许定义任何静态内容;
    因为实力内部类属于外部类的对象
    但是static final是可以定义的;final属于常量,是在常量池中维护;

  2. 外部类静态方法中不能直接访问实例内部类数据;
    静态方法要想调用非静态成员,则需要创建对象;来调用
    不能直接使用内部类数据,要通过外部类对象创建内部类对象访问

  3. 如果外部类成员变量、内部类成员变量、内部类方法中局部变量同名

    • 外部类成员: 外部类.this.变量名
    • 内部类成员: this.变量
    • 局部变量: 变量
    • 优先使用局部变量
    package day13;
    class Outer2{
        int x = 11;// 外部类成员
        class Inner2{
            int x =22;// 内部类成员
            public void f(){
                int x =33;//局部变量
                System.out.println(x);
                System.out.println(this.x);
                System.out.println(Outer2.this.x);
            }
        }
    }
    public class TestInner2 {
        public static void main(String[] args) {
            Outer2 outer2 = new Outer2();
            Outer2.Inner2 inner2 = outer2.new Inner2();
            inner2.f();
        }
    }
    

静态成员内部类

内部类用static修饰

独立使用

School.WateFountain water=new School.WateFountain();
//非静态
    water.f();
    water.sf();
        实例化以后也可以调用静态方法
//静态
    School.WateFountain.sf();

注意:接口中可以定义静态内部类,静态内部接口,静态内部枚举

成员内部类继承问题

  1. 类在继承实例成员内部类时,需要调用实例成员内部类的构造方法来完成实例化;因此需要给该类的构造函数传递一个外部类的对象,使用enclosingClassReference.super();调用构造,实际上就是 外部类对象.super()

    package day13;
    
    class Outer3{
        Outer3(){
            System.out.println("outer3");
        }
        class Inner3{
            Inner3(){
                System.out.println("inner3");
            }
        }
        static class Inner4{
    
        }
    }
    // 顶级类 继承 实例成员内部类
    class Demo3 extends Outer3.Inner3{
        Demo3(Outer3 outer3){
            // 外部类的对象 来调用实例内部类的构造器
            outer3.super();
            System.out.println("Demo3");
        }
    }
    
    class Demo4 extends Outer3.Inner4 {
    
    }
    public class TestInner3 {
        public static void main(String[] args) {
            Demo3 d3 = new Demo3(new Outer3());
            Demo4 d4 = new Demo4();
        }
    }
    
    
  2. 子类内部类与父类内部类同名情况
    不会覆盖类,属于不同外部类(名称空间)

使用内部类

在顶级类中使用自己的内部类数据,需要创建内部类对象,不管是不是静态的内部类;

局部内部类

与局部变量是同一级别的

字节码文件

外部类名$N内部类名.class

语法

package day13;

public class TestLocalInner1 {
    public void f(){
        class BaseX{

        }
    }

    int n = 11;
    static int sn = 22;

    public static void main(String[] args) {
        int num = 11;
        // 局部内部类
        class BaseX{
            int x = 11;
            public  void show(){
                System.out.println(sn);
                System.out.println(new TestLocalInner1().n);
                // 可以访问局部变量,但是局部变量的值不允许修改;

            }
        }
        class SubX extends BaseX{
            public void show(){
                System.out.println("sdfs");
                System.out.println(x);
            }
        }


        SubX sx = new SubX();
        sx.show();

    }
}

注意

  1. 局部内部类不能声明静态成员,static final的变量除外
  2. 局部内部类处于静态方法中只能直接访问外部类静态成员。
  3. 局部内部类处于实例方法中可以直接访问外部类静态成员和实例成员;
  4. 局部内部类对局部变量的访问:可以访问局部变量,但是局部变量的值不允许修改,也就是只能赋值一次;

匿名内部类

字节码文件

外部类$N.class

场合

子类或实现类 只使用一次;

语法

new 父类(参数列表)|实现接口(){}

package day13;
interface Info1{
    void af();
}
/*class Info1Impl implements Info1{
    @Override
    public void af() {

    }
}*/
public class TestNoNameInner2 {
    // 匿名内部实现类,
    Info1 info1 = new Info1() {
        @Override
        public void af() {
            System.out.println("成员");
        }
    };
    public static void main(String[] args) {
        new Info1(){
            @Override
            public void af() {

            }
        }.af();
    }
}

内部类和内部接口

package day13;

interface Info {
    // public static 内部类
    class Inner {
        int x = 11;
    }

    // public static 内部接口
    interface SubInfo {
        void af();

        default void df() {
        }

        static void sf() {
        }
    }

}

class Demo2 implements Info.SubInfo {// 实现内部接口

    @Override
    public void af() {
        Info.SubInfo.sf();// 静态方法
        this.df();// 默认方法
    }
}

class Demo1 implements Info {
    public void show() {
        // x
        System.out.println(new Inner().x);
        SubInfo.sf();
        // df 接口引用 -->实现类对象
        new Demo2().df();
        // 匿名内部类
        new SubInfo(){
            @Override
            public void af() {

            }
        }.df();
    }
}

public class TestStaticInner1 {
}

注意

  1. 必须实现一个接口或 继承 一个父类;
  2. 不能定义静态数据
  3. 不能定义构造器, 因为没有名字,但是构造块不需要名字,可以定义构造块
  4. 不能是抽象的(抽象类无法创建对象),可以是静态的;
  5. 传递参数--> 给父类构造器

针对不同接口实现匿名内部类

package day13;
interface IA{
    void af();
}

interface IB{
    void af();
}

class IAImpl implements IA,IB{
    // 匿名实现类
    IA ia = new IA() {
        @Override
        public void af() {

        }
    };

    IB ib = new IB() {
        @Override
        public void af() {

        }
    };



    @Override
    public void af() {
        System.out.println("abc");
    }
}
public class TestNoNameInner3 {
    public static void main(String[] args) {

    }
}

函数式接口

接口中的抽象方法的个数只能有一个,叫函数式接口

注解

@FunctionalInterface

Lambda的作用

替换 匿名内部类的繁琐语法

package day13;


import day9.Test;

class Parent{
    public void f(){
        System.out.println("parent");

    }
}

/*class Child extends Parent{
    public void f(){
        System.out.println("child");
    }
}*/
public class TestNoNameInner1 {
    // 成员  父类引用 --》子类对象
    Parent p1 = new Parent(){
        @Override
        public void f() {
            System.out.println("child");
        }
    };
    public static void main(String[] args) {
        // 匿名内部子类
        new Parent(){// 子类对象
            public void f(){
                System.out.println("child");
            }
            public void m(){

            }
        }.m();
        // 子类对象调用自己的方法;

        TestNoNameInner1 t1 = new TestNoNameInner1();
        t1.p1.f();// 不能调用子类特有的方法;


    }
}

语法

(形参列表)->{方法实现}

示例

package day13;


@FunctionalInterface
interface La{
    // 无参,无返回值
//    void af();
    // 带参无返回值
//    void af(int x);
    // 无参,带返回值
//    String af();
    // 带参,带返回值
    String af(String s1,String s2);
}
/*
class LaImpl implements La{
    @Override
    public void af() {

    }
}*/

public class TestLambda1 {
    /*La la7 = (str1,str2)->{return str1+str2};
    La la8 = (str1,str2)->str1+str2;*/

    /*La la5 = ()->{return "hello"};
    La la6 = ()->"hello";// 可以省略return;*/

   /* La la3 = (x) -> {
        System.out.println(x);
    };
    La la4 = x -> System.out.println(x);*/


    /*La la1 = ()->{
        System.out.println("abc");
    };
    La la2 = ()-> System.out.println("abc");*/
    public static void main(String[] args) {
        /*LaImpl la = new LaImpl();
        la.af();*/
        // 2. 匿名内部类
        /*new La(){
            @Override
            public void af() {
                System.out.println("abc");
            }
        }.af();*/
        // Lambda表达式,只能针对函数式接口
        /*TestLambda1 t = new TestLambda1();
        t.la1.af();*/

    }
}

如果只有方法实现只有一句代码,则可以省略{}
若是有返回值的方法,而方法实现只有一句,则可以省略{} 和return关键字

注意

Lambda 只能针对函数式接口
类型只能是函数式接口类型;(用来定位实现的接口)

匿名内部类和Lambda的表达式的区别

第一点:

  1. 匿名内部类可以继承一个类,也可以实现一个接口
  2. Lambda 只能实现接口

第二点:

  1. 匿名内部类实现接口 没有要求
  2. Lambda必须函数式接口;

第三点:

  1. 匿名内部类;可以调用默认方法default,
  2. Lambda 不可以调用默认方法;

方法引用

替代Lambda语法

四种情况

  1. 引用类方法(静态方法)
    类名:: 静态方法
  2. 引用特定对象的实例方法
    特定对象:: 实例方法
  3. 引用某类对象的实例方法
    类名::实例方法
  4. 引用构造器
    类名::new
package day13;



@FunctionalInterface
interface La1{
//    int f(String s);
    Student f(String s);
}

class Student{
    private String name;
    Student(String name){
        this.name = name;
    }
}

public class TestLambda3 {
    /*// 1. 引用类方法
    La1 la1 = s ->Integer.parseInt(s);
    La1 la2 = Integer::parseInt;

    // 2. 引用特定对象的实例方法
    La1 la3 = s -> {return "heelolle".indexOf(s);};
    La1 la4 = "hellohello"::indexOf;

    // 3.引用某类对象的实例方法
    La1 la5 = s -> {return s.length();};
    La1 la6 = String::length;*/

    // 4.引用构造器
    La1 la7 = s -> {return new Student(s);};
    La1 la8 = Student::new;



    public static void main(String[] args) {
        TestLambda3 t = new TestLambda3();
        /*int s = t.la1.f("44");
        System.out.println(s);
        System.out.println(t.la2.f("111"));*/
    }
}

posted @ 2018-10-03 00:54  耳_东  阅读(157)  评论(0)    收藏  举报