java 打印字符串内存地址 java输出内存地址_java输入语句


*异常捕捉和上报的联俄和使用,以及代码块是否执行逻辑

public class ExceptionTest06 {
 public static void main(String[] args) {
 System.out.println("main begin");
 try{
 //try尝试执行先
 m1();
 System.out.println("以上m1()出现异常的话,本句不执行");
 }catch(FileNotFoundException e){
 //这个分支中可以使用e引用,e引用保存的内存地址是那个new出来异常对象的内存地址。
 //catch是捕捉异常之后走的分支。
 //在catch分支中处理异常
 System.out.println("文件不存在,可能路径错误,也可能被删除了");
 e.printStackTrace();//当出现异常时候,此句为啥是在最后才执行喃?java.io.FileNotFoundException: D:Java学习笔记1Java学习笔记-03-常用类.java (系统找不到指定的文件。)
 }
 //try...catch把异常抓住以后,这里ide代码会继续执行。
 System.out.println("main over");
 }
 private static void m1() throws FileNotFoundException{
 System.out.println("m1 begin");
 m2();
 //以上m2()出现异常,下句over语句不执行
 System.out.println("m1 over");
 }
 private static void m2() throws FileNotFoundException{
 System.out.println("m2 begin");
 m3();
 //以上m3()出现异常,下句over语句不执行
 System.out.println("m2 over");
 }
 private static void m3() throws FileNotFoundException {
 //调用SUN jdk中某个类的构造方法
 //这个类还没有接触过,后期IO流的时候就知道了。
 //我们只是借助这个类学习一下异常处理机制。
 //创建一个输入流对象,该流指向一个文件。
 new FileInputStream("D:Java学习笔记Java学习笔记-03-常用类.java");
 //以上语句出现异常,下句语句不执行、
 System.out.println("如果以上代码出现异常,这里代码不会执行");
 /*
 编译报错的原因是什么?
 这里调用了一个构造方法:FileInputStream(Stream name);
 这个构造方法的声明位置上有:throws FileNotFoundException,
 FileNotFoundException的父类是IOException,IOException的父类是Exception,属于编译时异常
 最终得知:FileNotFoundException是编译时异常。
 错误原因?编译时异常要求程序员编写程序阶段必须对它进行处理,不处理编译器就报错。
 */
 /*
 我们采用第一种处理方式:
 在方法声明的位置上使用throws继续上抛,在方法声明上面加入throws FileNotFoundException
 一个方法体当中的代码出现异常之后,如果上报的话,此方法结束。
 只能上抛FileNotFoundException类或者其父类及以上的类。不能是其他异常类。
 一般不建议在main方法上使用throws,因为这个异常如果真正的发生了,一定会抛给JVM,JVM只能终止。
 异常处理机制的作用就是增强程序的健壮性。怎么能做到,异常发生了也不影响程序的执行。
 所以,一般main方法中的异常建议使用try...catch进行捕捉。main就不要继续上抛了。
 第二种方式:
 使用try...catch语句进行捕捉。
 这个异常就不会上报,自己把这个事儿处理了。
 异常上抛到此为止,不再上抛了。
 注意:
 只要异常没有捕捉,采用上报的方式,此方法的后续代码不会执行。
 另外需要注意:try语句块中的某一行出翔异常,该行后面的代码不会执行。
 try...catch捕捉异常之后,后续代码可以执行。
 */
 }
}
*try...catch深入
public class ExceptionTest07 {
 /*
 深入try...catch
 1.catch后面的小括号中的类型可以是i具体的异常类型,也可以是该异常类型的父类型。
 2.catch可以写多个。建议catch的时候,精确的一个一个处理,这样有利于程序的调试。
 3.catch写多个的时候,从上到下的Exception的范围必须遵守从小到大。
 4.在以后的开发中,处理编译时异常,应该上报还是捕捉呢?怎么选择?
 如果希望调用者知道异常并处理,选择throws上报。
 其他情况选择捕捉的方式。
 */
 public static void main(String[] args) {
 /*
 try{
 FileInputStream fis =new FileInputStream("D:Java学习笔记Java学习笔记-01-面向对象.java1");
 }catch(FileNotFoundException e){
 System.out.println("找不到该文件");
 e.printStackTrace();//java.io.FileNotFoundException: D:J1ava学习笔记Java学习笔记-01-面向对象.java (系统找不到指定的路径。)
 }
 */
 /*
 try{
 FileInputStream fis =new FileInputStream("D:Java学习笔记Java学习笔记-01-面向对象.java1");
 }catch(IOException e){ //多态。IOException e = new FileNotFoundException();
 System.out.println("找不到该文件");
 e.printStackTrace();//java.io.FileNotFoundException: D:J1ava学习笔记Java学习笔记-01-面向对象.java (系统找不到指定的路径。)
 }
 */
 /*
 try{
 FileInputStream fis =new FileInputStream("D:Java学习笔记Java学习笔记-01-面向对象.java1");
 }catch(Exception e){ //多态。Exception e = new FileNotFoundException();
 System.out.println("找不到该文件");
 e.printStackTrace();//java.io.FileNotFoundException: D:J1ava学习笔记Java学习笔记-01-面向对象.java (系统找不到指定的路径。)
 }
 */
 /*
 try{
 //创建输入流
 FileInputStream fis =new FileInputStream("D:Java学习笔记Java学习笔记-01-面向对象.java1");
 //读文件,如果上面创建输入流已经出现异常了,此句代码不执行了。
fis.read();
 }catch(FileNotFoundException e){
 System.out.println("找不到该文件");
 e.printStackTrace();//java.io.FileNotFoundException: D:J1ava学习笔记Java学习笔记-01-面向对象.java (系统找不到指定的路径。)
 }catch(IOException e){
 System.out.println("读文件报错了!");
 e.printStackTrace();
 }
 */
 //JDK8及以上版本的新特性
 try{
 //创建输入流
 FileInputStream fis =new FileInputStream("D:Java学习笔记Java学习笔记-01-面向对象.java1");
 //进行数学运算
 System.out.println(100/0);//这个异常是运行时异常,编写程序时可以处理,也可以不处理。
 }catch(FileNotFoundException | ArithmeticException|NullPointerException e){
 System.out.println("文件不存在?数学异常?空指针异常?都有可能!");
 e.printStackTrace();//java.io.FileNotFoundException: D:J1ava学习笔记Java学习笔记-01-面向对象.java (系统找不到指定的路径。)
 }
 }
}
*异常对象的常用方法
/*
异常对象有两个非常重要的常用方法:
 1.获取异常简单的描述信息:
 String msg = exception.getMessage();
 2.打印异常追踪的堆栈信息:
 exception.printStackTrace();
 */
public class ExceptionTest08 {
 public static void main(String[] args) {
 //这里只是为了测试getMessage()方法和printStackTrace()方法。
 //这里只是new了异常对象,但是没有将异常对象输出。JVM会认为这是一个普通的java对象。
 NullPointerException e = new NullPointerException("空指针异常");
 //获取异常简单描述信息:这个信息实际上就是构造方法上面String参数。
 String msg = e.getMessage();
 System.out.println(msg);//空指针异常
 //打印异常堆栈信息
 //java后台打印异常堆栈追踪信息的时候,采用了异步线程的方式打印的。
 e.printStackTrace();
 System.out.println("hello world!");
 }
}
异常对象的常用方法练习2
/*
异常对象的两个方法:
 String msg = e.getMessage();
 e.printStackTrace();//一般使用这个
我们以后查看异常的追踪信息,我们应该怎么看,可以快速的调式程序呢?
 异常信息追踪信息,从上往下一行一行看。
 但是需要注意的时:SUN写的代码就不用看了(看包名就知道是否是SUN公司的)。主要的问题时出现在自己编写的代码上。
 */
public class ExceptionTest09 {
 public static void main(String[] args) {
 try {
 m1();
 } catch (FileNotFoundException e) {
 //获取异常简单描述信息
 System.out.println(e.getMessage());
 //打印异常堆栈追踪信息!!!
 //在实际的开发中,建议使用这个,养成良好习惯。
 //这行代码要写上,不然出问题你也不知道。
 e.printStackTrace();
 /*
 java.io.FileNotFoundException: D:Java学习笔记Java学习笔记-01-面向对象.java1 (系统找不到指定的文件。)
 at java.base/java.io.FileInputStream.open0(Native Method)
 at java.base/java.io.FileInputStream.open(FileInputStream.java:219)
 at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157)
 at java.base/java.io.FileInputStream.<init>(FileInputStream.java:112)
 at com.kuangyixi.javase.exception.ExceptionTest09.m3(ExceptionTest09.java:52) at com.kuangyixi.javase.exception.ExceptionTest09.m2(ExceptionTest09.java:49) at com.kuangyixi.javase.exception.ExceptionTest09.m1(ExceptionTest09.java:46) at com.kuangyixi.javase.exception.ExceptionTest09.main(ExceptionTest09.java:18) 因为52行出问题导致了49行
 49行出问题导致了46行
 46行出问题导致了18行
 应该先查看52行的代码,52行是代码错误的根源。
 */
 }
 System.out.println("捕捉之后继续执行");
 }
 private static void m1() throws FileNotFoundException {
 m2();
 }
 private static void m2() throws FileNotFoundException {
 m3();
 }
 private static void m3() throws FileNotFoundException {
 new FileInputStream("D:Java学习笔记Java学习笔记-01-面向对象.java1");
 }
}
*try...catch和finally
/*
关于try...catch中的finally字句:
 1.在finally字句中的代码时最后执行,并且时一定会执行的,即使try语句块中的代码出现了异常。
 finally字句必须和try一起出现,不能单独编写。
 2.finally语句通常使用在哪些情况下呢?
 通常在finally语句块中完成资源的释放/关闭。
 因为finally中的代码比较有保障。
 即使try语句块中的代码出现异常,finally中代码也会正常执行。
 */
public class ExceptionTest10 {
 public static void main(String[] args) {
 FileInputStream fis=null;//声明位置放在try外面,这样在finally中才能用。
 try {
 //创建输入流对象
 fis = new FileInputStream("D:Java学习笔记Java学习笔记-01-面向对象.java");
 //开始读文件...
 String s = null;
 //这里一定会出翔空指针异常!
 s.toString();
 System.out.println("hello world!!!");
 //流使用完需要关闭,因为流是占用资源的。
 //即使以上程序出现异常,流也必须要关闭
 //放在这里有可能流关闭不了
//fis.close();
 } catch (FileNotFoundException e) {
 e.printStackTrace();
 } catch (IOException e) {
 e.printStackTrace();
 } catch (NullPointerException e){
 e.printStackTrace();
 } finally {
 System.out.println("hello haoke!");
 //流的关闭放在这里比较保险
 //finally中的代码时一定会执行的。
 //即使try中出现了异常!
 if (fis != null) {
 try {
 //close()方法有异常,采用捕捉的方式。
 fis.close();
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
 }
 System.out.println("hello kitty!!");
 }
}
*try和finally,没有catch
/*
finally语句
 放在finally语句块中的代码是一定会执行的。
 */
public class ExceptionTest11 {
 public static void main(String[] args) {
 /*
 try和finally,没有catch可以吗?可以。
 try不能单独使用。
 try finally可以联合使用。
 以下代码的执行顺序:
 先执行try...
 再执行finally...
 最后执行return(return语句只要执行方法必然结束。)
 */
 try{
 System.out.println("try....");
 return;
 }finally{
 System.out.println("finally...");
 }
 //这里不能写语句,因为这个代码是无法执行到的;
//System.out.println("hello world!!");
 }
}
*finally语句不执行的情况
/*
finally语句不执行的情况
 */
public class ExceptionTest12 {
 public static void main(String[] args) {
 try{
 System.out.println("try....");
 //退出JVM
 System.exit(0);
 //退出JVM之后,finally语句中的代码就不执行了。
 }finally{
 System.out.println("finally...");
 }
 }
}
*finally经典面试题
/*
finally面试题
 */
public class ExceptionTest13 {
 public static void main(String[] args) {
 int result = m();
 System.out.println(result);//100
 }
 /*
 java语法规则(有一些规则是不能破坏的,一旦这么说了,就必须这么做!):
 java中有一条这样的规则:
 方法体中的代码必须遵循自上而下顺序依次逐行执行(亘古不变的语法!)
 java中还有一条语法规则:
 return语句一旦执行,整个方法必须结束(亘古不变的语法!)
 */
 public static int m(){
 int i = 100;
 try{
 //return i;这行代码出现后JVM先保存i的值为100,待finally执行完毕后再返回100结束方法;
 //return语句还必须保证是最后执行的。一旦执行,整个方法结束。
 //这个return一定是最后执行的。
 return i;
 }finally {
 i++;
 }
 }
}
/*
反编译之后的效果
public static int m()
{
 int i = 100;
 int j = i;
 i++;
 return j;
 Exception exception;
 exception;
 i++;
 throw exception;
}
 */
*final finally finalize有什么区别?
/*
final finally finalize有什么区别?
 final 关键字
 final修饰的变量不能重新赋值,
 final修饰的方法不能被覆盖,
 final修饰的类不能被继承.
 finally 关键字
 和try联合使用。
 finally语句块中的代码是必须执行的。
 finalize 标识符
 finalize()是Object类中的一个方法名。
 这个方法是JVM的垃圾回收器GC负责调用。
 */
public class ExceptionTest14 {
 public static void main(String[] args) {
 //final是一个关键字。表示最终的。不变的。
 //final修饰的变量不能重新赋值,修饰的方法不能被覆盖,修饰的类不能被继承。
 //public static final 表示常量;
 final int i = 100;
 //i = 200;//不行
 //finally也是一个关键字,和try联合使用,使用在异常处理机制中
 //在finally语句块中的代码时一定会执行的。
 try{
 }finally{
 System.out.println("finally...");
 }
 //finalize()是Object类中的一个方法。作为方法名出现。
 //所以finalize是标识符。
 //finalize()方法是JVM的GC垃圾回收器负责调用。
 Object obj;
 }
}
*自定义异常类
/*
1.SUN提供的JDK内置的异常肯定是不够用的。在实际的开发中,有很多业务
这些业务出现异常之后,JDK中都是没有的。和业务挂钩的。那么异常类我们可以自己定义。
2.java中怎么自定义异常
 第一步:编写一个类继承Exception或者RuntimeException
 第二步:提供两个构造方法,一个无参数的,一个带有String参数的。
 */
//public class MyException extends RuntimeException{//运行时异常
public class MyException extends Exception{//编译时异常
 public MyException(){
 super();
 }
 public MyException(String s){
 super(s);
 }
}
*使用自定义异常类
public class ExceptionTest15 {
 public static void main(String[] args) {
 //创建异常对象(只new了异常对象,并没有手动抛出)
 MyException e =new MyException("用户名不能为空");
 //打印异常堆栈信息
 e.printStackTrace();
 //获取异常简单描述信息
 String msg =e.getMessage();
 System.out.println(msg);
 }
}
*自定义异常在实际开发中的作用
//测试改良之后的MyStack
//注意:以下案例,是异常最重要的案例。必须掌握。自定义异常在实际开发中的应用。
public class ExceptionTest16 {
 public static void main(String[] args) {
 //创建栈对象
 MyStack stack = new MyStack();
 //压栈
 try {
 stack.push(new Object());
 stack.push(new Object());
 stack.push(new Object());
 stack.push(new Object());
 stack.push(new Object());
 stack.push(new Object());
 stack.push(new Object());
 stack.push(new Object());
 stack.push(new Object());
 stack.push(new Object());
 //这里栈满了
 stack.push(new Object());
 } catch (MyStackOperationException e) {
//e.printStackTrace();
 System.out.println(e.getMessage());
 }
 //弹栈
 try {
 stack.pop(new Object());
 stack.pop(new Object());
 stack.pop(new Object());
 stack.pop(new Object());
 stack.pop(new Object());
 stack.pop(new Object());
 stack.pop(new Object());
 stack.pop(new Object());
 stack.pop(new Object());
 stack.pop(new Object());
 //这里栈已空了
 stack.pop(new Object());
 } catch (MyStackOperationException e) {
//e.printStackTrace();
 System.out.println(e.getMessage());
 }
 }
}
/*
栈操作异常:自定义异常
 */
public class MyStackOperationException extends Exception{ //编译时异常!
 public MyStackOperationException() {
 super();
 }
 public MyStackOperationException(String s) {
 super(s);
 }
}
public class MyStack {
 // 1/这个栈可以存储java中的任何引用类型的数据
 // 2/在栈中提供push方法模拟压栈。(栈满了,要有提示信息。)
 // 3/在栈中提供pop方法模拟弹栈。(栈空了,也要有提示信息。)
 // 4/编写测试程序,new栈对象,调用push pop方法来模拟压栈弹栈动作。
 private Object[] elements;
 //set和get也许用不上,但是必须协商,这是规矩。你使用IDEA生成就行了。
 //封装:第一步:属性私有化,第二部:对外提供set和get方法。
 //Alt+insert
 private int index;
 public void push(Object obj) throws MyStackOperationException {
 if (this.index>=elements.length-1) {
 /*
 改良之前
 System.out.println("栈已满,压栈失败");
 return;
 */
 //改良之后
 //创建异常对象
 MyStackOperationException e = new MyStackOperationException("栈已满,压栈失败");
 //手动将异常跑出去
 throw e;//这里捕捉没有意义,自己new一个异常,自己捉,没有意义。栈已满这个信息需要传递出去。
 //可以合并以上两行代码:throw new MyStackOperationException("栈已满,压栈失败");
 }
 this.index++;
 this.elements[index]=obj;
//所有System.out.println("引用")方法执行时,如果输出的是引用时,会自动调用引用的toString方法。
 System.out.println("压栈"+obj+"元素成功,栈帧指向"+index);
 }
 //弹栈就是往外取出元素,每取出一个,栈帧减1;
 public void pop(Object obj) throws MyStackOperationException {
 if (this.index<=-1){
 /*
 改良之前
 System.out.println("栈空了,弹栈失败");
 return;
 */
 //改良之后
 throw new MyStackOperationException("栈空了,弹栈失败");
 }
 System.out.print("弹栈"+elements[index]+"元素成功。");
 this.index--;
 System.out.println("栈帧指向"+index);
 }
 public int getIndex() {
 return index;
 }
 public void setIndex(int index) {
 this.index = index;
 }
 public Object[] getElements() {
 return elements;
 }
 public void setElements(Object[] elements) {
 this.elements = elements;
 }
 public MyStack() {
 //一维数组动态初始化
 //默认初始化容量为10
 this.elements=new Object[10];
 this.index = -1;
 }
}
*关于异常的方法覆盖
/*
重写之后的方法不能比重谢之前的方法抛出更多(更宽泛)的异常,可以更少。只是针对编译时异常,所有运行时异常除外。
这是之前讲解方法覆盖的时候遗留的问题
 */
public class ExceptionTest17 {
 public static void main(String[] args) {
 }
 public void doSome() { }
 public void doOther() throws Exception{ }
}
class Cat extends ExceptionTest17{
 //方法覆盖成功
 //public void doSome() throws RuntimeException{ }
 //方法覆盖失败
 //public void doSome() throws Exception{ }
 //方法覆盖成功
 //public void doOther() throws Exception{ }
 //方法覆盖成功
 //public void doOther() { }
 //方法覆盖成功
 //public void doOther() throws NullPointerException{ }
}
/*
总结异常中的关键字:
 异常捕捉:
 try
 catch
 finally
 throws 在方法声明位置上使用,表示上报异常信息给调用者
 throw 手动抛出异常!
 */
异常作业练习:
编写程序模拟用户注册:
1.程序开始执行时,提示用户输入“用户名”和“密码”信息。
2.输入信息之后,后台java程序模拟用户注册。
3.注册时用户要求长度在6-14]之间,小于或者大于都表示异常。
注意:
 完成注册的方法放到一个单独的类中。
 异常类自定义即可。
 class UserService{
 public void register(String username,String password){
 //这个方法中完成注册!
 }
 }

编写main方法,在main方法中接收用户输入的信息,在main方法中调用UserService的register方法完成注册。