Java的数据类型分两种:
基本类型:byte,short,int,long,boolean,float,double,char
引用类型:所有class和interface类型
引用类型可以赋值为null,表示空,但基本类型不能赋值为null
将基本类型类型用类封装
Java核心库为每种基本类型都提供了对应的包装类型,如java.lang.Boolean,java.lang.Double
核心库提供的包装类都是不变类(final),创建后是不变的
@jdk.internal.ValueBased
public final class Integer extends Number
implements Comparable<Integer>, Constable, ConstantDesc {
private final int value;
}
核心库提供的包装类实例必须使用equals对比不能使用==
Integer a = Integer.valueOf(111111111);
Integer b = Integer.valueOf(111111111);
System.out.println("a==b :" + (a == b));
System.out.println("equals:" + (a.equals(b)));
enum定义的类型是class,有以下几个特点:
enum Weekday {
MON(1, "星期一"), TUE(2, "星期二"), WED(3, "星期三"), THU(4, "星期四"), FRI(5, "星期五"), SAT(6, "星期六"), SUN(0, "星期日");
public final int dayValue;
private final String chinese;
private Weekday(int dayValue, String chinese) {
this.dayValue = dayValue;
this.chinese = chinese;
}
// 默认情况下,对枚举常量调用toString()会返回和name()一样的字符串
// toString()可以被覆写,而name()则不行
@Override
public String toString() {
return this.chinese;
}
}
读写方法符合以下这种命名规范的class被称为JavaBean
// 读方法:
public Type getXyz()
// 写方法:
public void setXyz(Type value)
JavaBean主要用来传递数据,即把一组数据组合成一个JavaBean便于传输。 此外,JavaBean可以方便地被IDE工具分析,生成读写属性的代码,主要用在图形界面的可视化设计中。
可以使用Java核心库提供的Introspector枚举JavaBean的所有属性
BeanInfo info = Introspector.getBeanInfo(Person.class);
for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
System.out.println(pd.getName());
System.out.println(" " + pd.getReadMethod());
System.out.println(" " + pd.getWriteMethod());
}
// 输出
// age
// public int base.Person.getAge()
// public void base.Person.setAge(int)
// class
// public final native java.lang.Class java.lang.Object.getClass()
// null
// name
// public java.lang.String base.Person.getName()
// public void base.Person.setName(java.lang.String)
其中”class”是从Object继承的getClass()方法带来的
从Java 14开始,引入了新的Record类
public class Main {
public static void main(String[] args) {
Point p = new Point(123, 456);
System.out.println(p.x());
System.out.println(p.y());
System.out.println(p);
}
}
public record Point(int x, int y) {}
除了用final修饰class以及每个字段外,编译器还自动为我们创建了构造方法,和字段名同名的方法,以及覆写toString()、equals()和hashCode()方法。
换句话说,使用record关键字,可以一行写出一个不变类。
Commons Logging和Log4j: 一个负责充当日志API,一个负责实现日志底层,搭配使用非常方便
把只定义了单方法的接口称之为FunctionalInterface,用注解@FunctionalInterface标记,
@FunctionalInterface
public interface Callable<V> {
V call() throws Exception;
}
// 使用Lambda表达式,我们就可以不必编写FunctionalInterface接口的实现类,从而简化代码:
Arrays.sort(array, (s1, s2) -> {
return s1.compareTo(s2);
});
public class FunctionalProgrammingDemo {
static int cmp(String s1, String s2) {
return s1.compareTo(s2);
}
// 从Java 8开始,我们可以用Lambda表达式替换单方法接口
void SortStrings(String[] strs) {
Arrays.sort(strs, new Comparator<String>() {
public int compare(String s1, String s2) {
return s1.compareTo(s2);
}
});
}
/*
* Lambda
* 参数是(s1, s2),参数类型可以省略,因为编译器可以自动推断出String类型。-> { ...}
* 表示方法体,所有代码写在内部即可。Lambda表达式没有class定义,因此写法非常简洁。
*/
void LambdaSortStrings(String[] strs) {
Arrays.sort(strs, (s1, s2) -> {
return s1.compareTo(s2);
});
// 等同于 Arrays.sort(array, (s1, s2) -> s1.compareTo(s2));
}
// 还可以引入签名一致的方法
// 这里,方法签名只看参数类型和返回类型,不看方法名称,也不看类的继承关系
public static void main(String[] args) {
String[] array = new String[] { "Apple", "Orange", "Banana", "Lemon" };
Arrays.sort(array, FunctionalProgrammingDemo::cmp);
System.out.println(String.join(", ", array));
}
}