JAVA基础知识|小知识点

1、强烈建议,不使用char类型

那么,到底为什么java里不推荐使用char类型呢?其实,1个java的char字符并不完全等于一个unicode的字符。char采用的UCS-2编码,是一种淘汰的UTF-16编码,编码方式最多有65536种,远远少于当今Unicode拥有11万字符的需求。java只好对后来新增的Unicode字符用2个char拼出1个Unicode字符。导致String中char的数量不等于unicode字符的数量。

然而,大家都知道,char在Oracle中,是固定宽度的字符串类型(即所谓的定长字符串类型),长度不够的就会自动使用空格补全。因此,在一些特殊的查询中,就会导致一些问题,而且这种问题还是很隐蔽的,很难被开发人员发现。一旦发现问题的所在,就意味着数据结构需要变更,可想而知,这是多么大的灾难啊。

2、final修饰的常量

用关键字final指示常量,关键字final表示这个变量只能被赋值一次,一旦被赋值,就不能再更改了,习惯上,常量名使用全大写。

如果经常希望某个常量可以在一个类中的多个方法中使用,通常将这些常量称为类常量,使用关键字static final修饰。

3、检查字符串是否为null也不为空串

if (str != null && str.length() != 0) {
System.out.println("字符串不为空");
} else {
System.out.println("字符串为空");
}

4、“==”与“equals”的区别

“==”:

1)用于比较值类型(int、float、boolean等)

2)用于比较引用类型,如果两个对象的引用地址相同,则返回true

“equals”:

1)用于比较引用类型,默认情况下与“==”的返回结果相同

2)由开发者覆写此方法,自己定义逻辑。比如常见的String类对此方法的覆写,覆写过后,即使两个对象的引用地址不同,返回结果仍然可以相同

    public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}

5、Objects.equals(A,B)与A.equals(B)比较

查看源码,会发现Objects.equals(A,B)方法在比较之前,会先检查A是否为空,避免程序报空指针的异常

    public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}

6、LocalDate与Date

如果只想对日期进行操作,而不对时间点进行操作,建议使用LocalDate类,而不是Date类,前者拥有更多的操作方法,后者的方法已经逐渐被废弃

7、在将父类转换成子类之前,应该使用instanceof进行检查

Object obj = "test";
if (obj instanceof String) {
String str = (String) obj;
System.out.println(str);
}

尽量避免进行强制类型转换,可以通过重新设计父类的方式,来避免这种操作

8、public class 与 class

public class是公共类的意思,public是访问修饰符。java规定一个类文件中,public修饰的class只有一个,并且类名必须和这个类的文件名一样,所以一个类文件中可以有多个类,但由public修饰的类只能有一个

备注:protected、private很少会用于修饰类

9、public、protected、private修饰符

这里说的修饰,主要是对类中的方法、域等进行修饰

在说明这四个关键字之前,我想就class之间的关系做一个简单的定义,对于继承自己的class,可以认为他们都是自己的子女,而对于和自己一个目录(同一个包路径)下的class,认为都是自己的朋友。
 
1、public:public表明该数据成员、成员函数是对所有用户开放的,所有用户都可以直接进行调用
 
2、private:private表示私有,私有的意思就是除了class自己之外,任何人都不可以直接使用,私有财产神圣不可侵犯嘛,即便是子女,朋友,都不可以使用。
 
3、protected:protected对于子女、朋友来说,就是public的,可以*使用,没有任何限制,而对于其他的外部class,protected就变成private。

作用域 当前类 同一个package 子孙类 其他package
public  √  √
protected  √ ×
private × × ×
default × ×

注:不写时默认为friendly

10、Integer.valueOf()与Integer.parseInt()

Integer.parseInt()把String类型转换为int类型
Integer.valueOf()把String类型转换为Integer对象

11、格式化输出

String message = String.format("Hello,%s.Next year,you'll be %d", "jyy", );
System.out.println(message);
System.out.printf("Hello,%s.Next year,you'll be %d", "jyy", );

转换符,不需要特意的记忆,使用的时候,再进行查找

12、switch语句

如果在case分支语句的末尾没有break语句,那么就会接着执行下一个case语句,这种情况相当危险,为此,我们程序中从不使用switch语句。

13、不定长数组-ArrayList

        //初始化
ArrayList<Car> arrayList = new ArrayList<>();
//添加
arrayList.add(new Car(1001, "奔驰", 200));
arrayList.add(new Car(1002, "宝马", 300));
//在中间位置添加
arrayList.add(1, new Car(1003, "保时捷", 500));
//修改
arrayList.set(0, new Car(1001, "奥迪", 400));
//查询
Car c = arrayList.get(0);
System.out.println(c.toString());
//删除
arrayList.remove(2);
//查询长度
arrayList.size();
//转数组
Car[] cars = new Car[arrayList.size()];
arrayList.toArray(cars);

对数组实施插入和删除元素的操作其效率很低。对于小型数组来说,这一点也不必担心。但如果数组存储的元素数比较多,又经常在中间位置插入、删除元素,就应该考虑使用链表来处理了。

14、类修饰符

只有内部类可以是私有类(private),而常规类只可以具有包可见性(默认),或公有可见性(public)

15、受检异常和非受检异常(运行时异常)

Error类和Exception类都是继承Throwable类,RunTimeException继承Exception类。

1、受检异常,编译会报错,开发时就必须处理。非受检异常,编译不会报错,一般是开发的漏洞或者失误,由人主导,尽量避免。

2、RunTimeException类、Error类及其子类,属于非受检异常,如:NullPointerException、IndexOutOfBoundsException等。

除了上面之外的异常属于受检异常。

备注:Error类是系统中的错误,只能通过修改程序才能修正。一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢等。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和和预防,遇到这样的错误,建议让程序终止。

3、如果方法里面抛出了受检异常,那么方法的签名必须throws这个异常,调用方也会被强制try-catch处理这个异常,这是编译级别的限制

   如果是RunTimeException或者Error类及其子类那就是非受检的,这种异常在方法内抛出,不需要在方法的签名上throws

如何使用?

1、如果抛出的异常是可恢复的,同时我们也期望API的调用者捕获异常进行恢复处理,那么我们应该使用受检异常。受检异常会强迫API的使用者截获异常并恢复处理,或者进行声明继续抛出。

2、虽然受检异常是Java语言一项很好的特性,它强迫程序员处理异常,大大增强程序的可靠性。但是过分的使用受检异常会使API使用非常不方便,调用者必须在catch块中处理所有的受检异常,或者调用者必须声明抛出这些受检异常。

总而言之,对于可恢复的情况,使用受检异常;如果不清楚是否可能恢复,则最好使用未受检异常。

16、String的特别之处

String虽然是引用类型,但是它可以不使用new关键字进行创建,而且创建的对象保存在常量池中,而不是堆中。如:String A ="abc";如果常量池中已经存在"abc",就会直接把引用传递给A,而不是生成新的"abc"。如果使用String A = new String("abc"),每一次调用都会在堆中生成新的对象。

17、try-with-resources

语法糖:建议将try-finally替换为try-with-resources

Connections, streams, files, and other classes that implement the Closeable interface or its super-interface, AutoCloseable, needs to be closed after use. 
Further, that close call must be made in a finally block otherwise an exception could keep the call from being made. Preferably,
when class implements AutoCloseable, resource should be created using "try-with-resources" pattern and will be closed automatically.

Java库中有很多资源需要手动关闭,比如InputStream、OutputStream、java.sql.Connection等等。在此之前,通常是使用try-finally的方式关闭资源;Java7之后,推出了try-with-resources声明来替代之前的方式。 try-with-resources 声明要求其中定义的变量实现 AutoCloseable 接口,这样系统可以自动调用它们的close方法,从而替代了finally中关闭资源的功能。

举个栗子,按照原本try-catch-finally的写法:

        OutputStream outputStream = null;
FileInputStream fileInputStream = null;
try {
outputStream = response.getOutputStream();
fileInputStream = new FileInputStream(xmlPath);
byte[] b = new byte[1024];
int i;
while ((i = fileInputStream.read(b)) > 0) {
outputStream.write(b, 0, i);
}
outputStream.flush();
} catch (Exception e) {
logger.error(e.toString());
} finally {
if (outputStream != null) {
outputStream.close();
}
if (fileInputStream != null) {
fileInputStream.close();
}
}

替换成try-with-resources之后:

            try (FileInputStream fileInputStream = new FileInputStream(xmlPath); OutputStream outputStream = response.getOutputStream()) {
byte[] b = new byte[1024];
int i;
while ((i = fileInputStream.read(b)) > 0) {
outputStream.write(b, 0, i);
}
outputStream.flush();
} catch (Exception e) {
logger.error(e.toString());
}

try-with-resources将会自动关闭try()中的资源,并且将先关闭后声明的资源。

18、@Suppresswarnings

@Suppresswarnings注解,可以消除代码中的警告,可以作用于类、属性、方法、方法入参、构造函数和方法的局部变量。

关键字 描述
all to suppress all warnings (将方法块里面所有的warning都取消)
cast to suppress warnings relative to cast operations
dep-ann to suppress warnings relative to deprecated annotation (取消对已弃用的注释的警告)
deprecation to suppress warnings relative to deprecation( 使用了不赞成使用的类或方法时的警告)
fallthrough
to suppress warnings relative to missing breaks in switch statements(当 Switch 程序块直接通往下一种情况而没有 Break 时的警告。)
finally to suppress warnings relative to finally block that don’t return(任何 finally 子句不能正常完成时的警告)
hiding to suppress warnings relative to locals that hide variable(取消对隐藏变量的警告)
incomplete-switch
to suppress warnings relative to missing entries in a switch statement (enum case) (取消对switch里面缺少case条目的警告)
null to suppress warnings relative to null analysis(取消对null分析的警告)
nls to suppress warnings relative to non-nls string literals (取消对 non-nls字符串的警告)
path 在类路径、源文件路径等中有不存在的路径时的警告。
rawtypes
to suppress warnings relative to un-specific types when using generics on class params (当在类参数中使用非特定的泛型时,取消警告)
restriction to suppress warnings relative to usage of discouraged or forbidden references (取消使用不鼓励或禁止的引用的警告)
serial
to suppress warnings relative to missing serialVersionUID field for a serializable class(当在可序列化的类上缺少 serialVersionUID 定义时的警告。)
static-access
to suppress warnings relative to incorrect static access(取消不正常的静态访问的警告)
synthetic-access to suppress warnings relative to unoptimized access from inner classes
unchecked
to suppress warnings relative to unchecked operations(执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型。)
unqualified-field-access to suppress warnings relative to field access unqualified
unused to suppress warnings relative to unused code (将未使用的方法的warning取消)
WeakerAccess 禁止“Access can be private”的警告
上一篇:全连接神经网络二分类


下一篇:第二十九节:Java基础知识-类,多态,Object,数组和字符串