java解惑学习经历(一)

解惑是一本关于java基础的书籍,内jdk版本较低,但仍值得一读,有很多基础但非常重要的思想。

下面进行一些举例和解惑:

1:

package com.gcc.javaRiddle;

import java.math.BigDecimal;

public class Accuracy {
	public static void main(String[] args) {
		System.out.println(2.00-1.4+"元");
		System.out.println(200-140+"分");
		System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.4")));
	}
	
}

最常见的数字迷惑,精度计算, java小数默认是double类型,计算小数会有精度缺失,这时如果你从事的是金融相关的项目要非常注意这一点,在金融上面精度缺失是致命的!有面试金融或者电商一类单位的同志们也注意下此类数据的处理。

* 解决方案1,改变单位,将小数改为整数用int或long来计算 * 解决方案2,用BigDecimal,注意new对象用string类型

运行结果:

0.6000000000000001元
60分
0.60

2:

package com.gcc.javaRiddle;

public class BiggestValue {
	public static void main(String[] args) {
		int count=0;
		for (int i = Integer.MAX_VALUE-100; i <=Integer.MAX_VALUE; i++) {
			count++;
		}
		System.out.println(count);
	}
	
}

不太会遇到,但又可能遇到的问题,这里提个醒。

运行结果:

结果是死循环,因为i++根本做不到比自己类型上线还大的数值

教训:在用数值时要时刻注意上溢和下溢

3:

package com.gcc.javaRiddle;

import java.math.BigInteger;
public class BigProblem {

	public static void main(String[] args) {
		BigInteger bigInteger1 = new BigInteger("500");
		BigInteger bigInteger2 = new BigInteger("5000");
		BigInteger bigInteger3 = new BigInteger("50000");
		BigInteger total = BigInteger.ZERO;
		total.add(bigInteger1);
		total.add(bigInteger2);
		total.add(bigInteger3);
//		total=total.add(bigInteger1);
//		total=total.add(bigInteger2);
//		total=total.add(bigInteger3);
		System.out.println(total);
	}
	
}
不太会遇到的迷惑,这里用来清晰一个概念。

BigInteger是不可变的,同理还有String,BigDecimal,Integer,Long,Short,Byte,Character,Boolean,Float,Double这类包装类型,不能改变这些的值,对这些类型的操作返回的是新的实例。不要被误导不可变类型是可变的。

运行结果:

0

4:

package com.gcc.javaRiddle;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * 在关闭流的时候不能直接连续写:in.close()和out.close();因为在第一个流关闭时报错会导致第二个流没有正常关闭;
 * 使用try catch来防止这种错误。
 * try catch:捕获错误,并让程序往下走完
 *
 */
public class CloseProblem {

	public static void main(String[] args) throws IOException {
		String src="";//源数据
		String dest="";//目的路径
		CloseProblem.copy(src, dest);
	}

	@SuppressWarnings("null")
	static void copy(String src, String dest) {
		InputStream in = null;
		OutputStream out = null;
		byte[] buf = new byte[1024];
		int n;
		try {
			while((n=in.read(buf))>=0){
				out.write(buf,0,n);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(in!=null){
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(out!=null){
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
	}
	
}

一个规范的要求,要多关注异常处理,注意内容见代码内注释

5:

package com.gcc.javaRiddle;

public class ConString {
	public static void main(String[] args) {
		System.out.println("a"+"b");
		System.out.println('a'+'b');
	}

}
一个很容易被忽视的类型char,一旦使用易发的错误。这里进行解释。

* 第一行输出是字符串,所有结果是拼接结果
* 第二行输出是字符型字面常量,所有结果是加法运算,会拓宽原生类型,char自动转为int
运行结果:

ab
195

6:

package com.gcc.javaRiddle;

public class GetValue {
	public static void main(String[] args) {
		
		int j=0;
		for (int i = 0; i < 100; i++) {
			j=j++;
		}
		System.out.println(j);
		
		
		int k=0;
		for (int i = 0; i < 100; i++) {
			k++;
		}
		System.out.println(k);
		
	}
	
}
一个一时手贱,看半天又会自觉觉得没问题的写法,这里给出解释。

* j=j++的执行顺序是,j赋值给j得0,j加1但并没有赋值,j仍为0

运行结果:

0
100
7:

package com.gcc.javaRiddle;

public class Indecision {
	public static void main(String[] args) {
		System.out.println(decision());
	}

	@SuppressWarnings("finally")
	private static boolean decision() {
		try {
			return true;
		} catch (Exception e) {
			
		} finally{
			return false;
		}
	}
	
}
一个可以向新手程序员秀一秀的技巧,也是偶尔可能遇到的错误。

* finally的返回值重于try
* 不论try是否出错,若finally有返回值,都将丢掉try的返回值
运行结果:

false

8:

package com.gcc.javaRiddle;
import java.util.Calendar;

public class InitOrder {

//	static int CURRENT_YEAR = Calendar.getInstance().get(Calendar.YEAR);
	static InitOrder initOrder=new InitOrder();
	int size;
	static int CURRENT_YEAR = Calendar.getInstance().get(Calendar.YEAR);
	
	private InitOrder() {
		size=CURRENT_YEAR-1990;
	}
	
	private int getSize(){
		return size;
	}
	
	public static void main(String[] args) {
		System.out.println("InitOrder size is:"+initOrder.getSize());
	}
	
}
静态常量也是一些java新手比较陌生的对象,因为使用的不是特别的频繁,这举一个错误例子。

* 目的是在InitOrder初始化过程中给size赋值。而CURRENT_YEAR也是静态的,赋值操作只会在上一个静态域完成后再执行
* 所以CURRENT_YEAR还是缺省值0
* 修改静态变量赋值循序即可。

教训:使用到静态变量时要多注意声明的位置。

运行结果:

InitOrder size is:-1990

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值