异常
自定义异常
定义异常与测试异常的具体步骤如下:
-
定义一个普通类(不包含主方法),
-
定义一个异常类,分为两种情况
-
一是继承于Exception,编译时就能报错
注意:编译时报错,无论你传入的何值,都必须先处理了
-
一种继承于RuntimeException,需要运行时报错
-
-
在刚才的普通类中,在合适的位置制作异常,并将其抛出
-
定义一个测试类,根据普通类创建对象,调用对象,测试是否能够根据我们的想法实现报错.
示例如下;
/*
自定义编译时异常的类:
编译三步:
一、定义一个异常类继承于Exception
二、定义一个测试类,在测试类中,定义是否需要制造异常类,并将其抛出,使调用者报错
三、主方法入口
自定义运行时异常的类:
编译三步:
一、定义一个异常类继承于Exception
二、定义一个测试类,在测试类中,定义是否需要制造异常类,并将其抛出,使调用者报错
三、主方法入口
*/public class DefindeException01 {
public static void main(String[] args) {
//创建对象
Person p=new Person("哈哈",15);
//1.6测试编译时异常,编译时异常,就是必须处理,处理所有的可能性
//p.setAge(15);//这里就应该有异常
//2.6测试运行时异常
p.setName(null);
}
}
//自定义异常类
//1.1需求:编译时,出现年龄异常直接报错,条件为 大于150或小于0
//1.2直接或间接的继承自Exception 编译时异常
//1.4定义一个异常类(编译时异常)
class AgeException extends Exception{
public AgeException() {
super();
}
}
//2.1需求:运行时,判断name是否为null,为null就报错
//2.2直接或间接的继承自RuntimeException 运行时异常
//2.4定义一个异常类(编译时异常)
class NameException extends RuntimeException{
//2.4.1在构造函数中可以传入要在控制台的值,并打印出来
public NameException(String str) {
super(str);
}
}
//1.3新建一个类,直接在该类中判断是否需要 报异常
//2.3新建一个类,直接在该类中判断是否需要 报异常
class Person{
private String name;
private int age;
//空构造函数
public Person() {
super();
}
//有参构造函数
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
//设置器和获取器
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
//2.2在获取器中,判断是否需要制造异常
if(name==null){
/*这里的字符串信息将会打印在控制台
* 这里是通过调用 构造器NameException->父构造器RuntimeException->父构造器Exception
* 直接打印出来的
*/
throw new NameException("哈哈,打错了");
}
}
public int getAge() {
return age;
}
public void setAge(int age) throws AgeException {
this.age = age;
//2.5在获取器中,判断是否需要制造异常
if(age>150||age<0){
throw new AgeException();
}
}
}
System.out.print小知识点
- 字符直接打印是里面的内容即字符串本身
- 数组直接打印是数组在内存中的地址
- 字符直接打印是里面的内容即数组本身
示例
public class Demo {
public static void main(String[] args) {
int a=5;
int i=10;
String s="haha";//""就是String类型的一个对象
String s1=new String("kk");//与上一行的相同
test(s);
test(s1);
int[] arr={1,2,3,4};
test(arr);//数组打印的是地址
System.out.println(arr);
char[] ch={'a'};
System.out.println(ch);//字符,打印是内容
}
static void test(String s){
System.out.println(s);
}
static void test(int[] x){
System.out.println(x);
}
}
常用类-String
字符串中的常量池
public class StringDemo01 {
public static void main(String[] args) {
String str1=new String("abc");
String str2="abc";//重新赋值
System.out.println(str1==str2);//两个新对象 false
/*因为 str1 在堆中新建对昂
*而 str2 在字符串常量中没有找到abc,也创建了新对象
*所以不同
*/
String str3="abc";
System.out.println(str2==str3);//true
/*采用字面值的方式创建一个字符串时,JVM首先会去字符串池中查找是否存在"abc"这个对象
如果不存在,则在字符串池中创建"abc"这个对象,然后将池中"abc"这个对象的地址赋给
str3,这样str3会指向池中"abc"这个字符串对象
如果存在,则不创建任何对象,直接将池中"abc"这个对象的地址返回,赋给str3。因为
str2、str3指向同一个字符串池中的"abc"对象,所以结果为true。
*/
}
}
字符串的长度获取、编码转换以及字符转字符串
//length(),获取字符串对象的长度
System.out.println(str3.length());//3
//字符串的解码与编码
//字符转字符串,俗称String编码
String name="小王";
//采用 对象.方法(),实现解码的功能,默认为utf-8
byte[] bs=name.getBytes();//默认为utf-8字符编码格式
System.out.println("这是是解码后的:");
System.out.println(Arrays.toString(bs));//[-48, -95, -51, -11]
//采用 String(byte[] byte) 根据参数字节数组,构建字符串
//根据String类的构造函数,参数为byte[] byte,生成一个String对象并返回
String x=new String(bs);
System.out.println("这里是编码后的:");
System.out.println(x);
/*
* String(byte[] bytes, int offset, int length, String charsetName)
通过使用指定的字符集解码指定的 byte 子数组,构造一个新的 String。
String(byte[] bytes, String charsetName)
通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String
*/
byte[] bs1=name.getBytes("gbk");//指定编码格式为utf-8,并解码
System.out.println("指定gbk格式解码后:"+Arrays.toString(bs1));
String bs2=new String(bs1,"gbk");
System.out.println("指定gbk格式编码后:"+bs2);
/*
* String(char[] value)
分配一个新的 String,使其表示字符数组参数中当前包含的字符序列。
String(char[] value, int offset, int count)
分配一个新的 String,它包含取自字符数组参数一个子数组的字符。
*/
char[] ch={'a','s','5','号','k'};
//ch转字符串
String sb3=new String(ch);
System.out.println(sb3);
//指定范围,转成字符串
//String(char[] value, int offset, int count) offset是索引开始,count是个数
String sb4=new String(ch,1,3);//从索引为1的开始,取3个数
System.out.println(sb4);
字符串其他一些常用方法
public class StringDemo02 {
public static void main(String[] args) {
String str1="shanghaishangxuetanG";
String str2="SHanghaishangxuetang";
/* 方法
* *** char charAt(int index) 返回指定索引处的 char 值。
*/
System.out.println("charAt(2):"+str1.charAt(2));//a
// int codePointAt(int index) 返回指定索引处的字符(Unicode 代码点)。
System.out.println("codePointAt(2):"+str1.codePointAt(2));
// int compareTo(String anotherString) 两个字符进行比较
System.out.println("compareTo(2):"+str1.compareTo(str2));
//int compareToIgnoreCase(String str) 两个字符比较,忽略大小写
System.out.println("compareToIgnoreCase(2):"+str1.compareToIgnoreCase(str2));
//***String concat(String str) 将指定字符串连接到此字符串的结尾。
System.out.println("concat(2):"+str1.concat(str2));
System.out.println(str1);
//***boolean contains(CharSequence s) 当且仅当此字符串包含指定的 char 值序列时,返回 true。
System.out.println("contains:"+str1.contains("tanG"));
/*
* boolean endsWith(String suffix) 测试此字符串是否以指定的后缀结束。
boolean startsWith(String prefix) 测试此字符串是否以指定的前缀开始。
*/
System.out.println("endsWith:"+str1.endsWith("tanG"));
System.out.println("startsWith:"+str1.startsWith("SHang"));
/* Sring类
* byte[] getBytes()
* byte[] getBytes(String charsetName)
* 字符串转成字节数组
*/
//解码用 方法 字符转字符串 采用方法
String bo="xiaon";
byte[] bs1=bo.getBytes();
System.out.println("解码后:"+Arrays.toString(bs1));
//编码 String(byte[] byte)
//编码用构造函数 字符串转字符 采用构造函数
String str10=new String(bs1);
/*
* ***int indexOf(String str) 返回指定子字符串在此字符串中第一次出现处的索引。
* int indexOf(String str, int fromIndex)
*/
System.out.println("indexOf:"+str1.indexOf("h"));//1
System.out.println("indexOf:"+str1.indexOf("h",2));//5 从索引为2的位置开始找
/*
* ***String replace(char oldChar, char newChar)
*/
System.out.println("replace:"+str1.replace("h","H"));//str中h全部替换为H,新字符串
System.out.println("replace:"+str1);//字符串不可变
/*
* ***String[] split(String regex) 用regex分隔
*/
String str3="xaow=nag";
System.out.println(str3);
System.out.println(Arrays.toString(str3.split("=")));
/*
* *** String substring(int beginIndex) 返回一个新的字符串,它是此字符串的一个子字符串。
*/
//一定需要开始和结束的索引 如果只有一个不生效
System.out.println("测试");
System.out.println("substring:"+str3.substring(1,3));
/*
* *** char[] toCharArray() 将此字符串转换为一个新的字符数组。
*/
System.out.println("toCharArray:"+Arrays.toString(str3.toCharArray()));
/*
* *** String toLowerCase() 转小写
* String toUpperCase() 转大写
*/
System.out.println("toLowerCase:"+str3.toLowerCase());
System.out.println("toUpperCase:"+str3.toUpperCase());
/*
* *** trim() 去收尾空格
*/
String str4=" 哈哈 ";
System.out.println("trim:"+str4.trim());
int i=132;
//String中的静态方法ValueOF,将int转成 String类型
//计算length的长度
System.out.println(String.valueOf(i).length());//3
}
}
总结:
- 其他数据基本数据类型转String,有两种方法
-
通过String的构造函数,可以达到
//第一种 用构造函数 String str2=new String(arr1); System.out.println(str2);
-
通过String类型的静态方法ValueOf(i)可以达到相同的目的
//第二种 用静态方法 valueOf String str3=String.valueOf(arr1); System.out.println(str3);
-
StringBuilder和StringBuffer
- StringBuilder: 线程不安全的,相对效率高
- StringBuffer : 线程安全的,相对效率低
/* StringBuilder:线程不安全,效率相对较高
* StringBuffer :线程安全,效率较低
*/
public class StringDemo04 {
public static void main(String[] args) {
//StringBuilder 默认初始容量为16
StringBuilder sb=new StringBuilder();
//int capacity() 初始容量
System.out.println(sb);
System.out.println(sb.capacity());//初始容量为16
System.out.println(sb.length());//长度为0
//StringBuilder(CharSequence seq)
StringBuilder sb2=new StringBuilder("abd");//str.length()+16
System.out.println(sb2);//abd
System.out.println(sb2.capacity());//16+3=19
System.out.println(sb2.length());//3
//StringBuilder(int capacity)
System.out.println(new StringBuilder(30).capacity());//30
//append(内容) 追加
StringBuilder ss=sb2.append(true);
System.out.println(ss);
System.out.println(sb2);
System.out.println(ss==sb2);//是在同一个对象上进行追加
//StringBuilder delete(int start, int end)
ss=sb2.delete(1, 3);//索引1-2的内容删除
System.out.println(ss);
System.out.println(sb2);
System.out.println(ss==sb2);
// StringBuilder insert(int offset, String str)
ss=sb2.insert(2, "TT");//从索引为2的位置开始插入
System.out.println(ss);
System.out.println(sb2);
System.out.println(ss==sb2);
//StringBuilder reverse() 翻转
ss=sb2.reverse();
System.out.println(ss);
System.out.println(sb2);
System.out.println(ss==sb2);
//Stirng 与StringBuilder|StringBuffer对象
System.out.println("1.String的构造器");
System.out.println("1.StringBuilder的构造器");
System.out.println("1.StringBuilder的toString");
System.out.println(sb.capacity());//16
sb.append("0123456789123456");
System.out.println(sb.capacity());//34
sb.append("1");
//只要内容长度超过了16就在原来的基础上乘以2+2
System.out.println(sb.capacity());//2*n+2 34
}
}
基本数据类型的包装类
基本数据类型 | 引用数据类型 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
boolean | Boolean |
char | Character |
自动拆装箱
自动装箱
从基本数据类型到引用数据类型
自动拆箱
从引用数据类型到基本数据类型
示例
public class DataDemo01 {
public static void main(String[] args) {
int i=10;//基本数据类型
Integer in1=i;//自动装箱
Integer in2=Integer.valueOf(i);//与上面一行实现相同的效果
System.out.println(3+in1);//自动拆箱
int i2=in1;//自动拆箱
int i3=in1.intValue();//与上面一行实现相同的效果
}
}
基本数据类型与包装引用数据类型的比较
- 基本数据类型与对象的包装类型的数据比较,只要值相同,无论是否new都相等,因为会发生自动拆箱
- 两个new肯定不相等,因为两个地址
- Integer和new Integer肯定不相等,一位一个是在堆中
- 如果两个Integer对象比较,在奇范围内 -128~127之间就相等,缓冲区对象,否则范围new
常量池
- 基本数据类型与对象的包装类的数据进行比较,主要值形同,无论是new的,都相同
- 两个new肯定不相同
- Integer和new Integer肯定不相等,一是在常量池,一个是在堆中
- 如果两个Integer对象比较,在其范围内,-128-127之间就相等,缓冲区对象,否则就new对象
public class DataDemo02 {
public static void main(String[] args) {
Integer i1=101;//常量池
Integer i2=101;//常量池
Integer i3=128;//常量池
Integer i4=128;//常量池
Integer i5=new Integer(101);;//堆 对象
Integer i6=new Integer(101);//堆 新对象
int i=101;
//常量池 -128-127之间 相等,否则不等
System.out.println(i1==i2);//true
System.out.println(i3==i4);//false
//两个new对象不等
System.out.println(i5==i6);//false
//与基本数据类型相比,无论是new Integer还是Integer对象
//都会发生自动拆箱,变成两个基本数据类型值的比较
System.out.println(i1==i1);//true
System.out.println(i1==i5);//true
}
}
时间类
时间类-Date
import java.util.Date;
/*
* Date 日期类 类Date表示特定的瞬间,精确到毫秒
*/
public class DateDemo {
public static void main(String[] args) {
Date date1=new Date();
//获取当前时间,以默认形式展示
System.out.println(date1);
//Date(long) 1970 年 1 月 1 日 00:00:00 GMT)以来的指定毫秒数
Date date2=new Date(123465441456354L);
System.out.println(date2);
//long getTime() 毫秒数
System.out.println(date1.getTime());
//toString()
System.out.println(date1.toString());
//toLocalString()
System.out.println(date1.toLocaleString());
//after
System.out.println(date2.after(date1));
}
}
日期格式转换类:SimpleDateFormate
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
*
* 日期格式转换类:SimpleDateFormate
* 字符串转为日期对象
* Date parse("字符串") 字符串转为日期对象
* 日期对象转为字符串
* String formate(date) 日期转字符串
*
*
*/
public class SimpleDateFormateDemo02 {
public static void main(String[] args) throws ParseException {
Date date=new Date();
SimpleDateFormat simple=new SimpleDateFormat();
//日期对象转字符串
String str=simple.format(date);
System.out.println(str);
//字符串转日期对象
Date d=simple.parse("2020-10-10 下午4:00");
System.out.println(d);
//按样输出
SimpleDateFormat simple2=new SimpleDateFormat("yyyy年mm月dd日 E hh:mm:ss SSS");
System.out.println(simple2.format(date));
String k=simple2.format(date);//日期对象转字符串
System.out.println(k);
Date date3=simple2.parse(k);//字符串转日期对象
System.out.println(date3);
}
}
枚举类
枚举是一个被命名的整型常数的集合,用于声明一组带标识符的常数 。说白了就是在生活中,以限定词的去描述事物的所有可能性,就像一周只有七天,周一到周日,一年只有四季,春夏秋冬。枚举中的成员都是这个类的一个实例
注意:枚举中的成员都是默认被public static final修饰的,且构造私有化(无法通过外部创建枚举的实例)
/*
* 枚举类:一种事物的所有可能性,所有情况
* enum定义枚举
* 只要是枚举都会隐式的继承自java.lang包下的enum
* 枚举类中的成员,都是该类的一个实例,默认修饰符位public static final
*/
public class EnumDemo01 {
public static void main(String[] args) {
Week sun=Week.Sunday;//声明并指定为枚举中的一个实例
System.out.println(sun.toString());//返回枚举的实例
switch(sun){//jdk1.6之后,可在switch中用枚举
case Monday:
sun.setName("礼拜一");
break;
case Tuesday:
sun.setName("礼拜二");
break;
case Wednesday:
sun.setName("礼拜三");
break;
case Thursday:
sun.setName("礼拜四");
break;
case Friday:
sun.setName("礼拜五");
break;
case Saturday:
sun.setName("礼拜六");
break;
case Sunday:
sun.setName("礼拜日");
break;
default:
sun.setName("不存在");
break;
}
sun.test();
}
}
//定义枚举
enum Week{
Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday;//枚举中的成员
private String name;
public String getName(){
return name;
}
public void setName(String name){
this.name=name;
}
public void test(){
System.out.println(name+"haha");
}
}