1、泛型
泛型类:
public class ClassName<T>{
private T data;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
泛型接口:
public interface IntercaceName<T>{
T getData();
}
实现接口时,可以选择指定泛型类型,也可以选择不指定, 如下:
指定类型:
public class Interface1 implements IntercaceName<String> {
private String text;
@Override
public String getData() {
return text;
}
}
不指定类型:
public class Interface1<T> implements IntercaceName<T> {
private T data;
@Override
public T getData() {
return data;
}
}
泛型方法:
private static T 方法名(T a, T b) {}
public class Demo {
public static void main(String[] args) {
print(123123);
}
public static <A> void print(A a){
System.out.println(a);
}
泛型限制类型
- 在使用泛型时, 可以指定泛型的限定区域 ,例如: 必须是某某类的子类或 某某接口的实现类,格式:
<T extends 类或接口1 & 接口2>
public class Demo {
public static void main(String[] args) {
Plate <Apple> = new Plate<>();
}
}
interface Fruit{ }
class Apple implements Fruit{}
class Plate<T extends Fruit>{
T data;
}
泛型中的通配符 ?
类型通配符是使用?代替方法具体的类型实参。
1 <? extends Parent> 指定了泛型类型的上届
2 <? super Child> 指定了泛型类型的下届
3 <?> 指定了没有限制的泛型类型
//未加通配符前
//不能将一个装着 苹果的盘于,看做一个装着水果的盘刊
Plate<Fruit> p = new Plate<Apple>(); 错
//加通配符后:指定了泛型类型的上届
//不能将一个装着苹果的盘于,看做一个装着水果的盘于
Plate<? extends Fruit> p = new Plate<App1e>();
//指定了泛型类型的下届
Plate<? super Apple> p = new Plate<Fruit>();
2、objects类:
public class Demo2 {
public static void main(String[] args) {
Person p1 = null;
Person p2 = new Person();
System. out. println(p1. equals(p2));
}
}
空指针异常:
使用Objects类库中的equals比较去比较:
public class Demo2 {
public static void main(String[] args) {
Person p1 = null;
Person p2 = new Person();
System.out.println(objects.equals(p1,p2))
}
}//返回值为false
Objects下的equals方法:
//多了一步空指针比较
public static boolean equals(object a, object b) {
return (a == b) || (a != null && a.equals(b));
}
Objects下的isNull方法:
//源码:判断obj是否为空
public static boolean isNull(object obj) {
return obj == nu11;
}
Objects下的nonNull方法:
//源码:判断obj是否为不空
public static boolean nonNull(0bject obj) {
return obj != null;
}
objects类库中的requireNonNull方法:
//源码:为空,抛出一个异常;不为空返回obj
public static <T> T requireNonNull(T obj) {
if (obj == nul11)
throw new NullPointerException();
return obj;
}
public class Demo2 {
public static void main(String[] args) {
Person p1 = null;
system.out.println(Objects.requireNonNull(e1));
}
}
//抛出一个异常:
3、Math类
编程时用到数学运算时,首先应该想到用Math类。
public class Demo2 {
public static void main(String[] args) {
System.out.println(Math.abs(-100));
System.out.println(Math.min(100,200));
System.out.println(Math.max(100 , 200));
//四舍五入
System.out.println(Math.round(100.5));
System.out.printIn(Math.round(-100.5));|
//返回小于等于参数的最大整数
System.out.println(Math.floor(3.5));
System.out.println(Math.floor(-3.5));
//返回大于等于参 数的最小整数
System.out.println(Math.ceil(3.5));
System.out.println(Math.ceil(-3.5));
}
}
4、Array类
Array类下的toString方法
public class Demo2 {
public static void main(String[] args) {
int[] arr = {8,1,2,3,4,5,6,7};
System.out.println(arr);//数组的内存地址(哈希值)
System.out.printIn(Arrays.toString(arr));
}
}
输出结果:
[I@7c30a502
[8,1,2,3,4,5,6,7]
toString方法源码
public static String toString(int[] a) {
if (a == null)
return "null";
int iMax = a.length - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(a[i]);
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
Array类下的sort方法:
public class Demo1 {
public static void main(String[] args) {
int[] arr = {8,1,2,3,4,5,6,7};
System.out.println(arr);//数组的内存地址(哈希值)
System.out.println(Arrays.toString(arr));
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}
}
输出结果:
[I@7c30a502
[8, 1, 2, 3, 4, 5, 6, 7]
[1, 2, 3, 4, 5, 6, 7, 8]
Array类下的binarySearch方法:
public class Demo1 {
public static void main(String[] args) {
int[] arr = {8,1,2,3,4,5,6,7};
System.out.println(arr);//数组的内存地址(哈希值)
System.out.println(Arrays.toString(arr));
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
System.out.println(Arrays.binarySearch(arr,6));
}
}
输出结果:
[I@7c30a502
[8, 1, 2, 3, 4, 5, 6, 7]
[1, 2, 3, 4, 5, 6, 7, 8]
5
Array类下的copyOf方法:
public class Demo1 {
public static void main(String[] args) {
int[] arr = {8,1,2,3,4,5,6,7};
System.out.println(arr.length);
arr = Arrays.copyOf(arr,15);//数组扩容
System.out.println( arr.length);
}
}
输出结果:
8
15
5、BigDecimal
1 BigDecimal类
概念
通过在控制台运行0.1+0.2,会发现float和double 的运算误差,由于float类型和double类型在运算时可能会有误差,为了实现精确运算则需要借助java. math.BigDecimal类加以描述
常用构造方法.
public BigDecimal(String va1) {
}
常用方法
下述所有的运算方法,不会影响参与运算的数据本身,运算的结果会被封装为一个新的BigDecima1对象,这个对象会通过return返回出去。
- public BigDecimal add(BigDecimal augend):加法运算
- public BigDecimal subtract (BigDecimal augend) :减法运算
- public BigDecimal multiply(BigDecimal augend) :乘法运算
- public BigDecimal divide(BigDecimal augend):除法运算
package com.java.test;
import java.math.BigDecimal;
public class Demo2 {
public static void main(String[] args) {
BigDecimal d1 = new BigDecimal("0.1");
BigDecimal d2 = new BigDecimal("0.2");
BigDecimal sum = d1.add(d2);
BigDecimal sub = d2.subtract(d1);
BigDecimal multiply = d1.multiply(d2);
BigDecimal divide = d2.divide(d1);
System.out.println(d1);
System.out.println(d2);
System.out.println("和:"+sum);
System.out.println("差:"+sub);
System.out.println("积:"+multiply);
System.out.println("商:"+divide);
}
}
输出结果:
0.1
0.2
和:0.3
差:0.1
积:0.02
商:2
6、Date类
package com.java.test;
import java.util.Date;
public class Demo3 {
public static void main(String[] args) {
//创建一个当前时间的Date
Date date = new Date();
System.out.println(date.toString());
//当前时间减一天
long time = date.getTime() - (24*60*60*1000);
Date date2 = new Date(time);
System.out.println(date2.toString());
}
}
输出结果:
Tue Sep 15 21:43:24 CST 2020
Mon Sep 14 21:43:24 CST 2020
7、DateFormat
DateFormat是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化和分析日期或时间。 日期/时间格式化子类(例如SimpleDateFormat )允许格式化(即,日期→文本),解析(文本“日期”)和规范化。 日期表示为Date对象或自1970年1月1日00:00:00 GMT以来的毫秒数。
package com.java.test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Demo4 {
public static void main(String[] args) throws ParseException {
/**
* y:年
* M:月
* d:日
* H:时
* m:分
* s:秒
*/
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//format:将date对象转换为字符串(yyyy-MM-dd HH:mm:ss)
String text = format.format(new Date());
System.out.println(text);
//parse:将yyyy-MM-dd HH:mm ss日期字符串 ,转换为date对象
Date date = format.parse("2019-09-15 22:08:05");
System.out.println((new Date().getTime()-date.getTime())/1000/60/60/24);
}
}
输出结果:
2020-09-15 22:17:57
366
8、String
String类表示字符串。 Java程序中的所有字符串文字(例如"abc" )都实现为此类的实例。
字符串是不变的; 它们的值在创建后无法更改。 字符串缓冲区支持可变字符串。 因为String对象是不可变的,所以可以共享它们。 例如:
String str = "abc";
字符串类是被Finall修饰的
方法区(Method Area),又称永久代(Permanent Generation), 又称非堆区(Non-Heap space)
方法区,常称为PermGen,位于非堆空间,又称非堆区(Non-Heap space)。
方法区是被所有线程共享。
所有字段和方法字节码,以及一些特殊方法如构造函数,接口代码也在此定义。
简单说,所有定义的方法的信息都保存在该区域,此区属于共享区间。
这些区域存储的是:静态变量 +常量+类信息(构造方法/接口定义) +运行时常量池。
但是,实例变量存在堆内存中,和方法区无关。
以上,只是逻辑上的定义。在HotSpot中,方法区仅仅只是逻辑上的独立,实际上还是包含在Java堆中,也是就说,方法区在物理上属于Java堆区中的一部分,而永久区(Permanent Generation) 就是方法区的实现。
堆(heap)
一个JVM实例只存在一个堆内存 ,堆内存的大小是可以调节的。类加载器读取了类文件后,需要把类、方法、常变量放到堆内存中,保存所有引用类型的真实信息,以方便执行器执行。
堆在逻辑上分为三部分(Perm) :
新生代:经过垃圾回收,但是垃圾回收次数小于15次的对象
老年代
永久代