一、控制台输入
首先讲讲System.in,这个“System”类的“in”的属性是做什么的呢?其实是个标准输入流InputStream类的对象,用来接收输入数据的。比如你的键盘的数据。
之前讲过System.out,这个out是个OutputStream是标准输出流,控制台打印的结果就是这个流输出出来的,如果想要从控制台输入,那就使用System.in这个属性。
怎么用呢?InputStream提供了read()方法,每次可以读入一个字符,如下图代码这样写:
点击运行后,控制台一片黑,那你用鼠标点击控制台,控制台就会获取焦点,光标就会到控制台上那你写个1,然后回车试试,看下图!
诶?打印出来了49?这是为什么?
实际上read接受的是ASCII码,那什么是ASCII码?那我下图有个对照表,大家看一下
那大家看控制字符,找到1,对,就第4列,那前边对应的ASCII字符是不是就是49?如果不懂ASCII码,自己搜索一下吧,我这儿就不讲课外知识了,大家知道这个对照表就可以了。那大家试试输入1234,看会打印什么?是不是输出的还是49?那上边说了,每次可以读取一个字符,只能读取一个。大家该问了,如果我想打印hello world那我岂不累死,我需要一个个对应ASCII表找?其实不用,有办法输入一串字符串的,看下图:
大家写写代码,运行一下试试。有人问try catch是什么意思?这就是这两天要讲的知识了,今天暂时讲不到,后边再讲。那IOException是什么?这是你接触到的第一个异常,属于IO相关的异常,那异常的概念也会放到后边。另外关于数据流的概念,这里暂时也不多介绍,后边章节会详细讲,现在大家先学会如何在控制台输入,然后我们现在先进行逻辑控制的学习。
二、逻辑控制之条件语句if...else...
什么意思呢?字面意思,如果满足什么条件就怎样,否则就怎样!如下
书写方法1:
如果满足“条件”就执行逻辑。
if (条件) {
// 执行逻辑
}
如下图:
大家可能疑问,Integer.valueOf()是做什么用的?首先Integer是一个包装类,等讲完多态再跟大家讲装箱拆箱的知识,大家目前先这样用,valueOf()这个方法是把String类型的数据转为int类型,如果大家输入的不是数字,那大家会接触到第二个异常:NumberFormatException。
那大家会问一个等号(=)是赋值操作,那两个等号(==)是什么操作啊?这个是判断值是否相等的操作。比如number = 1,那number就被赋值1了,那这时如果通过number == 1来判断,返回的是boolean的true,大家看下图:
大家看,返回的是true,表示这个条件成立,number 是和 1相等的。另外还有个equals的判断,什么意思呢,大家看下图a:
大家是不是看不懂了?听我慢慢解释:首先两个(==)是判断的对象的地址是否是一样的,那其实判断的是对象是否是一样的,比如图b:
这样两个就都相等了,为什么呢?
首先大家应该还记得第5节讲过对象引用和堆栈的概念,每次new就是新建一个对象,就会分配一块内存,就有个内存地址保存在栈中,那引用其实就是引用的栈中的对象地址。
1、上边图a中new了两个对象,两个地址,那你的str的栈对应的地址就是第一个好,那你第二个strNew的栈对应的地址就是第二个好。所以地址不同,然而双等号(==)比较的就是地址,所以他们两个并不是同一个地址,所以不相等,条件结果为false。
那equals呢,比较的是String对象的值,实际上是String类中有个equals方法,方法中写的逻辑就是判断值是否相等。当然如果你自定义一个类,实际上是可以复写equals的方法的(同样后续再讲复写、重载的概念)来自定义逻辑的,所以equals的判断结果取决于对equals的实现。但是如果类没有实现equals,那实际上对比的是hashCode,hashCode的生成其实也是基于内存地址的,返回的是对象在内存中的地址,所以如果一个类没有实现equals,其实和==并没区别。那现在看到的其实是String中的equals对比的是值是否相等。
2、上边图b中strNew被赋值为str,那其实是str的地址给到了strNew对应的栈,那引用的其实还是str对应的对象的地址,所以无论==还是equals,那其实两个都是true。
3、还有一种特殊情况,看下图:
大家是不是又看不明白了?
在java虚拟机中,除了堆、栈还有常量池的概念,那字符串就是存放在常量池中,等基础讲完在将JVM的时候我会详细介绍jvm的堆栈方法区等概念,目前大家记住字符串是在常量池中,并且常量池中如果有了这个字符串,是不会再生成一个新的。
虽然都是字符串,new出来的和直接赋值是有区别的,new出来的String对象本身在堆中,但是String对象中的字符串其实还是在常量池中。那直接赋值的String呢,其实引用的直接就是常量池中的字符串,这是他们的区别。所以,你虽然是str和strNew,是两个栈,但指向了同一个常量池中的地址,必然相等。
大家明白这两个操作符了不?如果还不懂,留言吧。
上边代码中大家输入0,就会打印“我执行了!”,那大家输入其他数字试试,是不是没有打印?这就是逻辑判断生效了。
书写方法2:
如果条件结果是true,就执行结果1,如果条件是fale,就执行结果2
if (条件) {
// 执行逻辑1
} else {
// 执行逻辑2
}
如下图:
那看结果,我输入了1,但是条件判断是 i == 0 条件才会为true,我输入了1所以条件判断是false,所以打印了else中的话。
书写方法3:
如果条件结果1是true,就执行结果1,如果条件结果2是true,就执行结果2,如果两个条件都不满足,都是false,就执行逻辑3。
if (条件1) {
// 执行逻辑1
} else if (条件2){
// 执行逻辑2
} else {
// 执行逻辑3
}
其中else if是可以无限增加的,想增加多少条件判断都是可以的,比如下图:
那今天先写到这里吧,下次讲讲分支,大家有疑问的话,欢迎评论指正。