Lang包常用类
1.异常Exception与错误Error的区别?
2. 开发中 常见的异常都有哪些? 如何处理异常的?
2.1 RunTimeException
2.2 编译时异常(checked Exception)
3. throw vs throws ?
throw:
在方法体里面 1,控制流程 2. 异常信息的传递 3. 经常与自定义异常综合使用
throws:
在方法定义后面 声明抛出具体的异常类 ,
1. 包装类
面向对象的思想。 数据类型: 基本 引用
基本数据类型: 4类8种 —> 提供了8个包装类型 引用数据类型 null
基本数据类型 | 包装类型 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
int vs Integer?
相同点:
都是代表整型的数据。
不同:
int 基本类型 0
Integer 引用类型 null 提供了很多属性和方法
1.1 Integer
public final class Integer extends Number implements Comparable<Integer>
Integer(int value) 创建Integer对象
Integer(String s)
功能方法:
Integer.valueOf(int num);---> 自动装箱
int intValue()
static Integer valueOf(String s)
static int compare(int x, int y)
int compareTo(Integer anotherInteger)
int hashCode()
static int max(int a, int b)
static int min(int a, int b)
static int parseInt(String s)
static int parseInt(String s, int radix)
private final int value;// 形参传递 维护Integer的数据
1. 自动装箱 vs 自动拆箱
private static void demo1() {
//创建Integer对象
Integer num1 = new Integer(100);
Integer num2 = new Integer(100);
System.out.println(num1.toString());//重写了父类的toString
System.out.println(num2.toString());//重写了父类的toString
System.out.println("num1==num2:" + (num1 == num2));//false
Integer num3 = new Integer("100");//将字符串转换成整型的数据
System.out.println(num3);
//自动装箱 vs 自动拆箱
//自动装箱: 将基本类型的数据 装箱成 包装类类型的对象 boxing
//自动拆箱:将包装类类型的对象 拆箱成基本类型的数据 un-boxing
Integer num4 = 100;//基本类型int
System.out.println(num4);
System.out.println("num1==num4:" + (num1 == num4));//false
Integer num5 = 100;
System.out.println("num5==num4:" + (num5 == num4));//true
Integer num6 = 200;
Integer num7 = 200;
System.out.println("num6==num7:" + (num6 == num7));//false
}
2. 整数缓存池(数组)
LongCache ByteCache ShortCache CharacterCache
public static Integer valueOf(int i) {//-128 127
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
private static class IntegerCache {
static final int low = -128;
static final int high;//127
static final Integer cache[];//维护Integer对象
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];//256个元素
int j = low;//-128
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
3. parseInt
String 转换 int/Integer
public static int parseInt(String s, int radix)// -1001 10
throws NumberFormatException
{
/*
* WARNING: This method may be invoked early during VM initialization
* before IntegerCache is initialized. Care must be taken to not use
* the valueOf method.
*/
if (s == null) {
throw new NumberFormatException("null");
}
if (radix < Character.MIN_RADIX) {
throw new NumberFormatException("radix " + radix +
" less than Character.MIN_RADIX");
}
if (radix > Character.MAX_RADIX) {
throw new NumberFormatException("radix " + radix +
" greater than Character.MAX_RADIX");
}
int result = 0;//最终的结果变量
boolean negative = false;//是否是一个负数
int i = 0, len = s.length();// i 索引 len 字符串长度(字符个数)
int limit = -Integer.MAX_VALUE;
int multmin;
int digit;
// s = "-1001";
if (len > 0) {
char firstChar = s.charAt(0);//获得字符串指定索引的字符的数据
if (firstChar < '0') { // Possible leading "+" or "-"
if (firstChar == '-') {//判断第一个字符是否为-
negative = true;
limit = Integer.MIN_VALUE;
} else if (firstChar != '+')
throw NumberFormatException.forInputString(s);
if (len == 1) // Cannot have lone "+" or "-"
throw NumberFormatException.forInputString(s);
i++;
}
multmin = limit / radix;
while (i < len) {// 1<5
// Accumulating negatively avoids surprises near MAX_VALUE
digit = Character.digit(s.charAt(i++),radix);//将指定字符的数据 转换成 指定进制的数字
//digit=1 0
if (digit < 0) {
throw NumberFormatException.forInputString(s);
}
if (result < multmin) {
throw NumberFormatException.forInputString(s);
}
result *= radix;//result=result*radix;
if (result < limit + digit) {
throw NumberFormatException.forInputString(s);
}
result -= digit;//result = result-digit;
}
} else {
throw NumberFormatException.forInputString(s);
}
return negative ? result : -result;
}
1.2 Character
Character(char value)
public static void main(String[] args) {
Character character = 97;//自动装箱
// Character character2 = Character.valueOf((char)97);
Character character1 = new Character((char) 97);
System.out.println(character);
System.out.println(character1);
//0-9
System.out.println(Character.isDigit('1'));//判断字符是否是数字
System.out.println(Character.isLetter('A'));
System.out.println(Character.toLowerCase('A'));
System.out.println(Character.MIN_RADIX);
System.out.println(Character.MAX_RADIX);
//2 0 1
//8 0 - 7
//10 0-9
//16 0-9 A-F
//36 0-9 A-Z
//将指定字符转换成指定进制内的数字
//-1
System.out.println(Character.digit('0', 2));
//"123" 转换 123
//0-9 48-57
//模拟字符串转int parseInt
}
在类的属性中 定义属性的 就使用包装类型 进行定义
描述股票每天涨跌的情况
@Setter
@Getter
public class Stock {
private Integer id;
private String name;
private Double data;//记录每天的涨跌情况
public Integer a(int id) {
//形参: 也是包装类型
//返回值类型: 也可能是包装类型
return null;
}
}
Stock stock = new Stock();
//压根没有赋值成功
System.out.println(stock.getData());//0.0 持平的情况
//判断 null
2. Math
服务于几何运算 算术运算
public static void main(String[] args) {
System.out.println(Math.PI);
int random = (int) (Math.random() * 100 + 100);//0.0-1.0
System.out.println(Math.abs(-10));
System.out.println(Math.pow(2, 3));
System.out.println(Math.round(1.567));
System.out.println(Math.max(100, 2));
// System.out.println(Math.min());
System.out.println(Integer.max(10, 1));
}
3. Object
protected Object clone() 创建对象 克隆
boolean equals(Object obj) 比较2个对象是否一致
int hashCode() 获得对象的哈希码值
protected void finalize() GC回收对象
Class<?> getClass() 获得当前正在运行的类或者接口的Class文件(Class类的对象)
==> 类 接口 编译出来class文件 jvm加载class文件 肯定会创建与之对象的Class类的对象
String toString() 将对象转换成字符串
void notify() 在其它线程里面唤醒随机(1个)等待的线程
/ void notifyAll() 在其它线程里面唤醒所有等待的线程
void wait() 当前线程一直等待
/ void wait(long timeout) 当前线程在指定时间内一直等待
3.1 比较2个对象
public static void main(String[] args) {
User user1 = new User(1, "张三", 20);
User user2 = new User(2, "张三", 20);
System.out.println(user1 == user2);//内存地址值 false
//在正常中 2个对象应该是同一个人
System.out.println("user1.equals(user2):"+user1.equals(user2));//false
System.out.println(user1.hashCode());
System.out.println(user2.hashCode());
System.out.println(user1.toString());
System.out.println(user2);
//true Object的equals并不满足子类需求 重写父类的方法equals
//在java规范 重写equals 必须重写hashcode
// 优先使用hashcode比较
//如果2个对象哈希码值不一致 证明2个对象肯定不等 就不执行equals逻辑
//2个对象哈希码值也有可能是一致的 (但是不能完全相信) 但是由于底层hash算法的原因 不同对象的hashcode 也有可能是一致的
String string1 = new String("Ma");
String string2 = new String("NB");
System.out.println(string1.hashCode());//2484
System.out.println(string2.hashCode());
}
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode// 所有的属性都参与
@ToString
public class User {
private Integer id;
private String name;
private Integer age;
//只要是对象参与比较 2个方法都必须要重写
//重写equals 必须重写hashcode
//比较规则: 自定义的 利用工具自动生成
/* @Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(name, user.name) && Objects.equals(age,user.age);
}
@Override
public int hashCode() {
return Objects.hash(name,age);
}*/
//重写equals
/* @Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof User)) {
return false;
}
User user = (User) obj;
if (this == user) {
return true;
}
//2个对象比较
// if (!this.id.equals(user.id)) {
// return false;
// }
// if (!name.equals(user.name)) {
// return false;
// }
//
// if (!age.equals(user.age)) {
// return false;
// }
return id.equals(user.id) && name.equals(user.name) && age.equals(user.age);
}
//重写hashcode 每个属性值hashcode运算
//s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
@Override
public int hashCode() {
int result = 0;
result = result * 31 + id.hashCode();
result = result * 31 + name.hashCode();
result = result * 31 + age.hashCode();
return result;
}*/
}
3.2 克隆
克隆对象===> 创建对象
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@ToString
//实现标识接口
public class Student implements Cloneable {
private Integer id;// private final int value; 不可变
private String name;//private final char value[];
private String[] hobby;// 引用
//从父类继承的clone
@Override
public Student clone() {
Student student = null;
try {
student = (Student) super.clone();
//克隆的对象
//深客隆(遍历式克隆属性的数据)
// Arrays.copyOf(this.hobby,hobby.length);
student.setHobby(hobby.clone());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
System.out.println("类必须实现Cloneable接口");
}
return student;
}
}
public static void main(String[] args) {
String[] hobby = {"code", "game", "music", "sleep"};
Student student = new Student(1, "jim", hobby);
//克隆新的对象--->学生的对象
Student clone = student.clone();
System.out.println("student:" + student);//com.javasm.lang.Student@74a14482
System.out.println("clone:" + clone);//com.javasm.lang.Student@1540e19d
System.out.println(clone == student);//new
System.out.println("-----------------------------------");
student.setId(1001);
student.setName("jim1");
student.getHobby()[0] = "java code";
//代表着student/clone 共用的一块内存
//代表着student/clone 共用的一块内存
System.out.println("student:" + student);
System.out.println("clone:" + clone);
//参数传递: 值传递
//基本 包装类 String 数据传递
//数组 自定义的类 内存地址值传递
//浅克隆: super.clone()
//深克隆: 数组 自定义的类
}
3.3 引用
System.gc();
对象.finalize();
GC: 是否要回收对象 要看对象的引用 以及对象是否是一个无用的对象 (对象引用次数 可达性分析)
1. 强引用
在程序运行期间
Student student = new Student(1, "jim", hobby);
Student clone = student.clone();
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.javasm.lang.StudentTest.main(StudentTest.java:23)
public static void main(String[] args) {
//2.软引用 有用不是必须的对象
Student student = new Student(1,"jim",null);
// SoftReference<Student> softReference = new SoftReference<>(student); 缓存
// //就代表着student就由强引用变成了软引用
// //GC: 判断 内存不足的时候
//
// System.out.println(softReference.get());
// student = null;
// System.gc();
// System.out.println("-------------------------------");
// System.out.println(softReference.get());
//
if(内存不足){
回收软引用的对象
}
//3.弱引用 比软引用还弱的引用
/*WeakReference<Student> weakReference = new WeakReference<>(student);
System.out.println(weakReference.get());
student = null;
System.gc();
System.out.println("-------------------------------");
System.out.println(weakReference.get());*/
//4.幻引用(虚引用)
ReferenceQueue referenceQueue = new ReferenceQueue();
PhantomReference<Student> phantomReference = new PhantomReference<>(student,referenceQueue);
System.out.println(phantomReference.get());
}
4. Class
public static void main(String[] args) {
// Student student = new Student();
//1.加载Student.class 肯定会创建一个与之对应的Class的对象 Class<Student> aClass
//public final native Class<?> getClass(); 通配符 匹配任意的类型
//1. getClass()必须依赖于对象
// Class aClass = student.getClass();//jvm里面加载的某个类或者是接口的class文件
// //获得Class类对象 是实现反射的基础---> 框架底层的实现 开源框架
//
// System.out.println(aClass.toString());
// System.out.println(aClass.getName());//com.javasm.lang.Student
// System.out.println(aClass.getSimpleName());//Student
//2. 静态的属性class---> 在本项目内 访问本项目内类或者接口
// Class aClass = Student.class;
// System.out.println(aClass.toString());
// System.out.println(aClass.getName());//com.javasm.lang.Student
// System.out.println(aClass.getSimpleName());//Student
//3. Class.forName("类或者接口的全限定名称") 在第三方的框架里面 以及在本项目内访问第三方框架的类或者接口
try {
Class aClass = Class.forName("com.javasm.lang.Student1");
System.out.println(aClass.toString());
System.out.println(aClass.getName());//com.javasm.lang.Student
System.out.println(aClass.getSimpleName());//Student
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.out.println("jvm里面没有这个类或者接口class文件 类库jar没在项目的编译路经下");
}
}