你強任你強,我幹我本行——Java基礎(下)

8、流與文件

8.1 File類

File類能夠操做文件還能夠操做文件目錄,在整個file類最經常使用用到這些方法:
構造方法之一:public File(String pathname)
刪除文件:public boolean delete()
判斷文件是否存在:public boolean exists()
建立目錄:public boolean mkdirs()
獲取父路徑file對象:public File getParentFile()
注:
①這裏的pathname是本地路徑,File類對象既能表示一個特定文件,也能表示一個目錄,File類能夠獲取文件信息例如文件大小,沒法處理文件內容,若要操做文件內容能夠經過流
②路徑分隔符請用File.separator常量表示java

8.2 流

8.2.1 簡介

常常說到io時後面都跟着流這個詞,它很抽象表示任何有能力產出數據的數據源對象或者有能力接收數據的接收端對象.java全部的I/O機制都是基於數據流進行輸入輸出,按不一樣的角度能夠分紅:
①按數據流方向:輸入流和輸出流
②按處理數據的單位:字節流(1byte = 8bit)和字符流(1char = 2byte = 16bit)
③按功能:節點流(程序直接在數據源上讀寫數據)和處理流(在處理時包裝了下)
IO包中的類大部分派生自如下四種抽象類:設計模式

字節流 字符流
輸入流 InputStream Reader
輸出流 OutputStream Writer

8.2.2 InputStream與OutputStream

InputStream與OutputStream是面向字節形式的I/O僅支持8位字節流
InputStream表示輸入數據源包括:
①字節數組
②String對象
③文件
④管道
⑤其餘種類的流組成的序列
⑥其餘數據源,例如Internet鏈接等
數組

OutputStream表示輸出目標包括:
①字節數組
②文件
③管道
app

InputStream與OutputStream層次結構:
eclipse

8.2.3 Reader與Writer

Reader與Writer是面向字符形式的I/O兼容Unicode
節點流相對應:
ide

字節流 字符流
InputStream  /  OutputStream Reader  /  Writer
適配器: InputStreamReader  /  OutputStreamWriter
FileInputStream  /  FileOutputStream
FileReader  /  FileWriter
StringBufferInputStream(已棄用)  /  (無相應的類) StringReader  /  StringWriter
ByteArrayInputStream/ByteArrayOutputStream CharArrayReader  /  CharArrayWriter
PipedInputStream  /  PipedOutputStream PipedReader  /  PipedWriter
處理流(運用結構型設計模式:裝飾模式)相對應:
字節流 字符流
FilterInputStream  /  FilterOutputStream FilterReader  /  FilterWriter(抽象類,無子類)
BufferedInputStream  /  BufferedOutputStream
BufferedReader(有readLine())  /  BufferedWriter
PrintStream PrintWriter
LineNumberInputStream(已棄用) LineNumberReader
PushbackInputStream PushbackReader
Reader與Writer層次結構:

8.3 示例

8.3.1 文件操做

8.3.1.1 讀文件

public static String readFile(String fileName) {
        File file = new File(fileName).getAbsoluteFile();
        if (!file.isFile()) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        try (InputStreamReader isr = new InputStreamReader(new 
FileInputStream(file), "UTF-8"); BufferedReader br = new BufferedReader(isr)) { String str; while ((str = br.readLine()) != null) { sb.append(str).append("\r\n"); } } catch (IOException e) { e.printStackTrace(); } return sb.toString(); } 複製代碼

8.3.1.1 寫文件

public static void writeFile(String fileName, String msg) {
        File file = new File(fileName);
        try {
            BufferedWriter bf = null;
            try {
                bf = new BufferedWriter(new FileWriter(file, true));
                bf.write(msg);
                bf.newLine();
                bf.write(msg);
            } finally {
                if (bf != null) {
                    bf.flush();
                    bf.close();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
複製代碼

8.3.2 內存操做

public static void memoryOpt(){
        String msg = "hello world !!!";
        try(InputStream in = new ByteArrayInputStream(msg.getBytes());
            OutputStream out = new ByteArrayOutputStream();){
            int temp = 0;
            while((temp = in.read()) != -1){
                out.write(Character.toUpperCase(temp));
            }
            System.out.println(out);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
複製代碼

8.3.3 管道流

static class Writer implements Runnable {

        PipedOutputStream out;

        public Writer(PipedOutputStream out) {
            this.out = out;
        }

        @Override
        public void run() {
            try {
                String message = "I'm K^Joker";
                try {
                    out.write(message.getBytes());
                } finally {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    static class Reader implements Runnable {

        PipedInputStream in;

        public Reader(PipedInputStream in) {
            this.in = in;
        }

        @Override
        public void run() {
            byte data[] = new byte[1024];
            try {
                try {
                    int len = in.read(data);
                    System.out.println(new String(data, 0, len));
                } finally {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        PipedOutputStream out = new PipedOutputStream();
        PipedInputStream in;
        try {
            in = new PipedInputStream(out);
            Thread read = new Thread(new Reader(in));
            Thread write = new Thread(new Writer(out));
            read.start();
            write.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
複製代碼

8.3.4 對象流

public class Person implements Serializable {

    private String name;

    private transient Integer age;

    private final Integer height = 180;

    private static Integer weight = 160;

    private transient final String nickName = "取毛名";

    private transient static String phone = "110";

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", height=" + height +
                ", nickName='" + nickName + '\'' +
                '}';
    }

    public static void serialize() {
        File file = new File("E:" + File.separator + "serializable.txt");
        try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file))) {
            out.writeObject(new Person("K^Joker", 23));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void deserialize() {
        File file = new File("E:" + File.separator + "serializable.txt");
        try(ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));){
            Object obj = in.readObject();
            System.out.println(obj);
        } catch (IOException e){
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException {
//        serialize();
        deserialize();
    }
}
複製代碼

9、枚舉

9.1 特性

① 枚舉常常用來表示一組相同類型的常量,例如性別、學歷、日期。
② 枚舉是一種特殊的類,它與普通類同樣,不過構造器訪問修飾符只能private,enum關鍵字定義,默認繼承了 java.lang.Enum 類,故不能繼承其餘類,並實現了 java.lang.Seriablizable 和 java.lang.Comparable 兩個接口。 ③ 定義爲枚舉類後編譯器會加上final聲名,因此該類沒法被繼承 ④ 全部的枚舉值都是 public static final 的,且必須在第一行定義 ⑤ 若在枚舉中定義了抽象方法,那全部枚舉變量必須實現其抽象方法函數

9.2 實現機制

咱們先定義一個枚舉:ui

public enum ColorEnum {
    
        RED(), YELLOW(), BLUE();
    
    }
複製代碼

javac編譯,生成.class文件:
this

咱們能夠看到編譯器默認生成的構造方法是private修飾的,而後javap看一下編譯後的字節碼:
idea

咱們能夠看到枚舉其實就是一個類,而且該類被聲明爲final,繼承了Enum類,枚舉定義的變量被聲明爲public static final,另外多出了靜態代碼塊,和兩個靜態方法values()和valueOf()。Enum類是一個抽象類,主要有name(枚舉變量的名稱)和ordinal(枚舉變量的位置索引)兩個屬性,在多出的靜態代碼塊中作了這樣的操做:

RED = new ColorEnum("RED", 0);  
     YELLOW = new ColorEnum("YELLOW", 1);
     BLUE = NEW ColorEnum("BLUE", 2);
     $VALUES = new ColorEnum[]{RED, YELLOW, BLUE};
複製代碼

values()方法是返回$VALUES數組的複製,valueOf方法是根據傳入的變量名稱返回對應枚舉實例。從下面那張圖咱們能夠大體看出這些。

9.3 枚舉使用

① 枚舉能夠實現接口,具備抽象方法

public enum ColorEnum implements ColorInterface{

    RED("紅色"){
        @Override
        void say(){
            System.out.println("我是紅色");
        }
    }, YELLOW("黃色"){
        @Override
        void say(){
            System.out.println("我是黃色");
        }
    }, BLUE("藍色"){
        @Override
        void say(){
            System.out.println("我是藍色");
        }
    }; //必須第一行

    private String color;

    private ColorEnum(String color){
        this.color = color;
    }

    @Override
    public String getColor(){
        return color;
    }

    abstract void say();

    public static void main(String[] args) {
        System.out.println(ColorEnum.RED); //RED
        System.out.println(ColorEnum.RED.getColor()); //紅色
        System.out.println(ColorEnum.RED.name()); //RED
        System.out.println(ColorEnum.RED.ordinal()); //0
        for(ColorEnum color : ColorEnum.values()){
            System.out.println(color);   //RED YELLOW BLUE
        }
        ColorEnum.RED.say(); //我是紅色
    }

}
複製代碼

② 接口中使用枚舉

public interface Food {  
    enum Appetizer implements Food{  
        SALAD, SOUP, SPRING_ROLLS;
    }  
    enum Dessert implements Food{  
        FRUIT, TIRAMISU, GELATO  
    }  
}  
複製代碼

10、註解

10.1 基本註解

在java.lang包下,JAVA內置了5種註解
① @Override
表示當前的方法定義將覆蓋超類中的方法。若方法簽名對不上被覆蓋的方法編譯器會報錯,@Override只能做用於方法.
② @Deprecated
表示元素已過期,若使用了註解爲它的元素,編譯器會發出警告信息.
③ @SuppressWarnings
關閉不當的編譯器警告信息
④ @SafeVarargs
抑制堆污染警告
⑤ @FunctionalIterface
聲明接口爲函數式接口(函數式接口指接口中僅僅只包含一個抽象方法)

10.2 自定義註解

10.2.1 元註解

@Target 表示該註解能夠用於什麼地方,其ElementType參數包括:
CONSTRUCTOR: 構造器的聲明
FIELD: 域聲明(包括enum實例)
LOCAL_VARIABLE: 局部變量聲明
METHOD: 方法聲明
PACKAGE: 包聲明
PARAMTER: 參數聲明
TYPE: 類、接口(包括註解類型)或enum聲明
@Retention 表示須要在什麼級別保存該註解信息,其RetentionPolicy參數包括:
SOURCE: 註解將被編譯器弄丟
CLASS: 註解在class文件中可用,但會被JVM弄丟
RUNTIME: JVM運行期有效,能夠經過反射機制讀取註解的信息
@Documented 將此註解包含在Javadoc中
@Inherited 容許子類繼承父類中的註解

10.2.2 規則

註解元素可用的類型以下:
① 全部基本數據類型
② String
③ Class類型
④ Annotation
⑤ 以上全部類型的數組
注:
使用@interface自定義註解,默認繼承了java.lang.annotation.Annotation,只能用public或默認這兩個訪問修飾符,若只有一個參數成員,最好把參數名稱設爲"value",註解不支持繼承,能夠嵌套.

10.2.3示例

public class Person {

    @MyValidation(nullable = false, message = "姓名不能爲空")
    private String name;

    public Person(){

    }

    public Person(String name) {
        this.name = name;
    }
}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyValidation {

    boolean nullable() default true;

    String message() default "";

}

public class Validation {

    public void validate(Object object) throws Exception {
        Class obj = object.getClass();
        Field[] fields = obj.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            verify(field, object);
            field.setAccessible(false);
        }
    }

    private void verify(Field field, Object object) throws Exception {
        MyValidation mv = field.getAnnotation(MyValidation.class);
        if (mv != null && !mv.nullable()) {
            Object name = field.get(object);
            if("".equals(name) || name == null){
                throw new Exception(mv.message());
            }
        }

    }

    public static void main(String[] args) throws Exception {
        Validation v = new Validation();
//        v.validate(new Person(""));
        v.validate(new Person());
    }
}
複製代碼

11、結語

參考了《Thinking in java》和《java core》,整個java基礎有不少東西未寫例如反射,NIO,JUC、集合等後續會慢慢寫。。,最後提下本身經常使用的快捷鍵:(Eclipse,idea快捷鍵能夠設置成eclipse的) ① ctrl+o : 查看當前類有哪些屬性和方法 ② ctrl+h : 全局搜索 ③ ctrl+f : 當前文件搜索 ④ Alt+←/→ : 上一個/下一個光標所在位置 ⑤ ctrl+shift+f:格式化(不要所有格式化,否則code view很。。。) ⑥ Ctrl+l : 跳到某行 ⑦ ctrl+t : 直接從接口找到實現類 ⑧ f6/f8 : debug下一步/調到下個斷點 ⑨ ctrl+shift+r:打開資源列表 ⑩ alt+/:自動補全代碼或者提示代碼 ⑪ ctrl+d:刪除當前行 ⑫ ctrl+shift+o:導包 ⑬ Ctrl+/: 註釋代碼

相關文章
相關標籤/搜索