- 代碼塊
靜態代碼塊:有static修飾,屬于類,與類一起優先加載,自動執行一次
實例代碼塊:無static修飾,屬于對象,每次創建對象時,都會優先執行一次。
package com.itheima.code;import java.util.Arrays;public class CodeDemo1 {public static String schoolName;public static String[] cards = new String[3];//靜態代碼快:有static修飾,屬于類,與類一起優先加載,自動執行一次//基本作用:可以完成對象的靜態資源的初始化static{System.out.println("靜態代碼塊執行了");schoolName = "黑馬程序員";cards[0] = "大王";cards[1] = "小王";}public static void main(String[] args) {System.out.println("main方法執行了");System.out.println(schoolName);System.out.println(Arrays.toString(cards));} }
輸出:
靜態代碼塊執行了
main方法執行了
黑馬程序員
[大王, 小王, null]package com.itheima.code;public class CodeDemo2 {private String name;private String[] direction = new String[4];//實例代碼塊:無static修飾,屬于對象,每次創建對象時,都會優先執行一次。//基本作用:初始化對象的實例資源。{System.out.println("實例代碼塊執行了");name = "itheima";direction[0] = "N";direction[1] = "S";direction[2] = "E";direction[3] = "W";}public static void main(String[] args) {System.out.println("main方法執行了");new CodeDemo2();} }
輸出:
main方法執行了
實例代碼塊執行了
- 成員內部類
成員內部類創建對象的格式:外部類名稱.內部類名稱 對象名 = new 外部類名稱().內部類名稱();
可以直接訪問外部類的實例成員、靜態成員
可以拿到當前外部類對象,格式是:外部類名.this。
package innerClass;public class Outer {public static String schoolName = "黑馬";public static void test(){System.out.println("Outer.test()");}private int age;public void run(){}//成員內部類:無static修飾,屬于外部類的對象持有public class Inner{public void show(){System.out.println("show");//成員內部類中可以直接訪問外部類的靜態成員System.out.println(schoolName);test();//也可以直接訪問外部類的實例成員System.out.println(age);run();System.out.println(this);System.out.println(Outer.this);}} }
package innerClass;public class Test {//成員內部類創建對象的格式:// //外部類名稱.內部類名稱 對象名 = new 外部類名稱().內部類名稱();public static void main(String[] args) {Outer.Inner inner = new Outer().new Inner();inner.show();} } class People{private int heartBeat = 100;public class Heart{private int heartBeat = 80;public void show(){int heartBeat = 200;System.out.println(heartBeat);//200System.out.println(this.heartBeat);//80System.out.println(People.this.heartBeat);//100}} }
- 靜態內部類
靜態內部類:屬于外部類本身持有
靜態內部類中可以直接訪問外部類的靜態成員
靜態內部類中不可以直接訪問外部類的實例成員
創建格式:外部類名稱.內部類名稱 對象名 = new 外部類名稱.內部類名稱();
package Innerclass2;public class Outer {public static String schoolName ;private int age;//靜態內部類:屬于外部類本身持有public static class Inner{public void show(){//靜態內部類中可以直接訪問外部類的靜態成員System.out.println(schoolName);//靜態內部類中不可以直接訪問外部類的實例成員//System.out.println(age);報錯}} }
package Innerclass2;public class Test {public static void main(String[] args) {//創建格式:外部類名稱.內部類名稱 對象名 = new 外部類名稱.內部類名稱();Outer.Inner inner = new Outer.Inner();inner.show();} }
- 匿名內部類
匿名內部類實際上是有名字:外部類名$編號.class
匿名內部類本質是一個子類,同時會立即構建一個子類對象
package innerclass3;public abstract class Animal {public abstract void cry(); }
package innerclass3;public class Test {public static void main(String[] args) {//匿名內部類實際上是有名字:外部類名$編號.class//匿名內部類本質是一個子類,同時會立即構建一個子類對象Animal a = new Animal(){@Overridepublic void cry() {System.out.println("貓會喵喵喵叫");}};a.cry();} }
- 匿名內部類的常見使用形式:通常可以作為一個對象參數傳輸給方法使用
package innerclass3;public class Test2 {public static void main(String[] args) {//匿名內部類的使用形式:通常可以作為一個對象參數傳輸給方法使用Swim s1 = new Swim(){@Overridepublic void swim() {System.out.println("學生游泳慢");}};start(s1);start(new Swim() {@Overridepublic void swim() {System.out.println("老師游泳快");}});}public static void start(Swim s){System.out.println("開始");s.swim();System.out.println("結束");} } interface Swim{void swim(); }
- 匿名內部類使用場景
package innerclass3;import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;public class Test3 {//需求:創建一個登錄窗口,窗口上只有一個登錄按鈕public static void main(String[] args) {JFrame win = new JFrame("登錄窗口");win.setSize(400,300);win.setLocationRelativeTo(null);//居中顯示win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//退出程序JPanel panel = new JPanel();win.add( panel);JButton btn = new JButton("登錄");panel.add(btn);//java要求必須給這個按鈕添加一個點擊事件監聽器對象,這樣就可以監聽用戶的點擊操作,就可以做出反應。btn.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("點擊了登錄按鈕");}});win.setVisible(true);} }
- 使用comparator接口的匿名內部類實現對數組進行排序
package innerclass3;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;@Data @NoArgsConstructor @AllArgsConstructor public class Student {//姓名 年齡 private String name;private int age; }
package innerclass3;import java.util.Arrays; import java.util.Comparator;public class Test4 {public static void main(String[] args) {Student[] students = new Student[3];students[0] = new Student("張三", 18);students[1] = new Student("李四", 17);students[2] = new Student("王五", 19);//按照年齡從大到小排序Arrays.sort(students, new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {return o2.getAge() - o1.getAge();}});for (Student student : students){System.out.println(student.getName() + " " + student.getAge());}} }
- Lambda的認識
Lambda只能簡化函數式接口的匿名內部類
寫法:(被重寫方法的形參列表)->{被重寫方法的方法體代碼。}
package lambda; //Lambda只能簡化函數式接口的匿名內部類 //寫法:(被重寫方法的形參列表)->{被重寫方法的方法體代碼。} public class LambdaDemo1 {public static void main(String[] args) {Swim s = new Swim() {@Overridepublic void swimming() {System.out.println("我要開始游泳了");}};s.swimming();Swim s1 = () -> {System.out.println("我要開始游泳了");};s1.swimming();} } //函數式接口:只有一個抽象方法的接口。 @FunctionalInterface//聲明函數式接口的注解。 interface Swim{void swimming(); }
- Lambda的省略規則:用于進一步簡化Lambda表達式的寫法。
- 參數類型全部可以省略不寫。
- 如果只有一個參數,參數類型省略的同時“()”也可以省略,但多個參數不能省略“()”
- 如果Lambda表達式中只有一行代碼,大括號可以不寫,同時要省略分號“;”如果這行代碼是return語句,也必須去掉return。
//按照年齡從大到小排序 // Arrays.sort(students, new Comparator<Student>() { // @Override // public int compare(Student o1, Student o2) { // return o2.getAge() - o1.getAge();//按照年齡降序 // } // });// Arrays.sort(students, (Student o1, Student o2) -> { // return o2.getAge() - o1.getAge(); // });// Arrays.sort(students, ( o1, o2) -> { // return o2.getAge() - o1.getAge(); // });Arrays.sort(students, (o1, o2) ->o2.getAge() - o1.getAge());
靜態方法引用:類名::靜態方法名
package innerclass3;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;@Data @NoArgsConstructor @AllArgsConstructor public class Student {//姓名 年齡private String name;private int age;public static int compareByAge(Student s1,Student s2){return s2.getAge() - s1.getAge();} }
//按照年齡從大到小排序// Arrays.sort(students, (o1, o2) -> // o2.getAge() - o1.getAge() // );//靜態方法引用:類名::靜態方法名Arrays.sort(students, Student::compareByAge);
實例方法引用:對象名::實例方法
package innerclass3;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;@Data @NoArgsConstructor @AllArgsConstructor public class Student {//姓名 年齡private String name;private int age;private double score;//靜態方法public static int compareByAge(Student s1,Student s2){return s2.getAge() - s1.getAge();}//實例方法public int compareByScore(Student s1,Student s2){return Double.compare(s2.getScore(),s1.getScore());} }
//靜態方法引用:類名::靜態方法名Arrays.sort(students, Student::compareByAge);//實例方法引用:對象名::實例方法Student t = new Student();Arrays.sort(students, t::compareByScore);
- 特定類的方法引用:類型名稱::方法名
- 使用場景:如果某個Lambda表達式里只是調用一個特定類型的實例方法,并且前面參數中的第一個參數作為方法的主調,后面的所有參數都是作為改實例方法的入參,則此時就可以使用特定類型的方法引用。
package lambda;import java.util.Arrays;public class ddemo {public static void main(String[] args) {String[] names = {"Tom","Jerry","angle","Andy"};//忽略大小寫,進行升序排列Arrays.sort(names,(s1,s2) -> s1.compareToIgnoreCase(s2));//特定類型方法引用:類型名稱::方法名Arrays.sort(names,String::compareToIgnoreCase);System.out.println(Arrays.toString(names));} }
- 構造器引用:類名::new
- 使用場景:如果某個Lambda表達式里只是在創建對象,并且“->”前后參數情況一致,就可以使用構造器引用。