java学习记录

记录一下Java的学习记录。

文本文件的读取

import java.io*;
public class MainStart{
    public static void main(String args[]){
        String filePath = "./a.txt";
        FileInputStream fin = new FileInputStream(filePath);
        InputStreamReader reader = new InputStreamReader(fin, encoding);
        BufferedReader buffReader = new BufferedReader(reader);
        String strTmp = "";
        while((strTmp = buffReader.readLine())!=null){
            System.out.println(strTmp);
        }
        buffReader.close();
    }
}

在新版本的JAVA中提供了NIO, 可以一次性读取全部 JDK11以上版本可以

Path path = Paths.get("./a.txt");
String data = Files.readString(path);
System.out.println(data);

JDK8可以

Path path = Paths.get("D:/aa.txt");
List<String>  lines = Files.readLines(path);

也可以

var reader = Files.newBufferedReader(path, Charset.forName("GBK"));

static关键字

Java中的static关键字解析

  • static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途。

  • 对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。

  • 但是要注意的是,虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的。

  • static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。

  • static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。

  • 静态成员变量虽然独立于对象,但是不代表不可以通过对象去访问,所有的静态方法和静态变量都可以通过对象访问(只要访问权限足够)。 # java单件模式

java单件模式 * 饿汉式

是否 Lazy 初始化:否

是否多线程安全:是

实现难度:易

描述:这种方式比较常用,但容易产生垃圾对象。
优点:没有加锁,执行效率会提高。
缺点:类加载时就初始化,浪费内存。
它基于 classloader 机制避免了多线程的同步问题,不过,instance 在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中大多数都是调用 getInstance 方法, 但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化 instance 显然没有达到 lazy loading 的效果。
public class Singleton {  
    private static Singleton instance = new Singleton();  
    private Singleton (){}  
    public static Singleton getInstance() {  
    return instance;  
    }  
}
  • 双检锁/双重校验锁(DCL) JDK 版本:JDK1.5 起

    是否 Lazy 初始化:是

    是否多线程安全:是

    实现难度:较复杂

    描述:这种方式采用双锁机制,安全且在多线程情况下能保持高性能。 getInstance() 的性能对应用程序很关键。

public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    if (singleton == null) {  
        synchronized (Singleton.class) {  
        if (singleton == null) {  
            singleton = new Singleton();  
        }  
        }  
    }  
    return singleton;  
    }  
}
  • 枚举 JDK 版本:JDK1.5 起

    是否 Lazy 初始化:否

    是否多线程安全:是

    实现难度:易

    描述:这种实现方式还没有被广泛采用,但这是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。 这种方式是 Effective Java 作者 Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。不过,由于 JDK1.5 之后才加入 enum 特性,用这种方式写不免让人感觉生疏,在实际工作中,也很少用。 不能通过 reflection attack 来调用私有构造方法。

public enum Singleton {  
    INSTANCE;  
    public void whateverMethod() {  
    }  
}

java枚举类型(enum)

java 枚举常见用法

enum Car {
    lamborghini(900),tata(2),audi(50),fiat(15),honda(12);
    private int price;
    Car(int p) {
        price = p;
    }
    int getPrice() {
        return price;
    } 
}

比较两个 double 的大小

  • 一种方法
public static int compare(double double1, double double2)  {  
    BigDecimal data1 = new BigDecimal(double1);  
    BigDecimal data2 = new BigDecimal(double2);       
    return data1.compareTo(data2);
}
  • 第二种 通过相减之差是否足够接近零来判断是否相等 不相等的话直接用大于号小于号判断大小

java 文档注释

java 文档注释

List和数组的转换

List转换为Array可以这样处理:

ArrayList<String> list=new ArrayList<String>();

String[] strings = new String[list.size()];

list.toArray(strings);

反过来,如果要将数组转成List怎么办呢?如下:

String[] s = {"a","b","c"};
List list = java.util.Arrays.asList(s);