一,java的基本类型
字节型(byte),短整型(short),整型(int),长整型(long),字符型(char),浮点型(float),双精度型(double),布尔型(boolean)。
整数:
------------------------------------------------------
byte:–128~127 (-27 ~ 27-1)
short:–32,768 ~ 32,767 (-215 ~ 215-1)
int:–2,147,483,648 ~ 2,147,483,647 (-231 ~ 231-1)
long:2,036,854,775,808 ~ 9,223,372,036,854 (-263 ~ 263-1)
浮点型数:
------------------------------------------------------
float:3.4E–038~3.4E+038 (-2149 ~ 2149-1)
double:1.7E–308~1.7E+308 (-21074 ~ 21074-1)
字符:
------------------------------------------------------
这个组包括字符型(char,0~65,535),它代表字符集的符号,例如字母和数字。
布尔型:
------------------------------------------------------
这个组包括布尔型(boolean),它是一种特殊的类型,表示真/假值。
二,java基本类型的转换
public class HelloWord {
//region 属性
// 日志类加载
private static Logger LOGGER = Logger.getLogger(HelloWord.class);
// java的八大基本类型
private byte byteNum;
private short shortNum;
private int intNum;
private long longNum;
private float floatNum;
private double doubleNum;
private boolean boolNum;
private char charNum;
//endregion
// region 方法
// 基本类型相互转换
private void transformation(){
/** byte类型的范围为-128至127
* short类型的范围为-32768至32767
* int 类型的范围为-2147483648至2147483647
* long类型的范围不常用
* 采用强制类型转换将short类型的128转换成byte类型
* 结果为 -128
* 原因是short转byte后最高位被当作符号位
* 范围小的数据类型会自动转换为表示范围大的数据类型,
* 而表示范围大的数据类型转范围小的数据类型需要强制转换
* boolean类型不能转换成其他类型
* 表示范围从小到大:byte,short,char -> int -> long -> float -> double
**/
// short转byte
shortNum = 128;
byteNum = (byte)shortNum;
LOGGER.info("short数字 128 转byte:" + byteNum);
// byte,short,char表示范围在java中被看为一类,三者在计算时首先转换成int型
byte bN1 = 121;
byte bN2 = 7;
LOGGER.info("两byte相加的类型是:" + getType(bN1 + bN2));
byte bN3 = (byte)(bN1 + bN2);
LOGGER.info("当两个byte类型的数字相加超过byte范围时,结果为" + bN3);
// 表示范围小的与表示范围大的相加时,表示范围小的数据类型会自动转换成表示范围大的
shortNum = 1;
intNum = 2;
LOGGER.info("short类型加上int类型的结果类型为:" + getType(shortNum + intNum));
floatNum = 1f;
doubleNum = 1L;
LOGGER.info("int类型加上float类型的结果类型为:" + getType(intNum + floatNum));
LOGGER.info("int类型加上double类型的结果类型为:" + getType(intNum + doubleNum));
// char类型转int类型
// 按照字母的ASCII码进行转换
charNum = 'a';
intNum = charNum;
LOGGER.info("char转int:" + intNum);
}
// Integer的 == 与 equals 注意
private void compareWith(){
LOGGER.info("equals相同类型比较结果:" + new Integer(100).equals(100));
LOGGER.info("equals不同类型比较结果:" + new Long(0).equals(0));
Integer i1 = 59;
Integer i2 = Integer.valueOf(59);
Integer i3 = new Integer(59);
LOGGER.info("i1 == i2:" + (i1 == i2));
LOGGER.info("i1 == i3:" + (i1 == i3));
LOGGER.info("i2 == i3:" + (i2 == i3));
Integer i4 = 200;
Integer i5 = Integer.valueOf(200);
Integer i6 = new Integer(200);
LOGGER.info("i4 == i5:" + (i4 == i5));
LOGGER.info("i4 == i6:" + (i4 == i6));
LOGGER.info("i5 == i6:" + (i5 == i6));
}
// 判断数据类型的静态方法
private static String getType(Object object){
return object.getClass().toString();
}
// endregion
public static void main(String[] args){
HelloWord helloWord = new HelloWord();
helloWord.transformation();
helloWord.compareWith();
}
}
三,java的比较方式,以及它们的区别
有 == 与 equals两种方法。
“equals” 比较
首先看 Integer类中的equals 方法源码的一部分:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
equals 方法首先比较的是类型是否相同,如果类型不同直接返回false,类型相同比较值,值相同返回true。其他包装类中的equals方法大同小异,基本都是先判断是否是同一对象,再判断类型,最后判断值。
“==”比较
1. 基本类型之间互相比较:以值进行比较
2. 一边是基本类型,一边是包装类型
1) 同类型的进行比较,如Integer 与int,Long与long进行==比较时,会自动拆箱比较值
2) 不同类型之间进行比较,则会自动拆箱,且会进行自动向上转型再比较值(低级向高级是隐式类型转换如:byte<short<int<long<float<double,高级向低级必须强制类型转换)
3. 两边都是包装类型则直接比较引用地址,但是要注意IntegerCache除外。
四,java多线程实现方式
Java多线程实现有四种方式:
1,继承Thread类。首先创建一个Thread类的子类,然后重写run()方法。创建Thread子类的对象,通过调用该对象的start()方法即可启动线程。
/**
* 继承Thread类并重写run方法
*/
class WindowsByThread extends Thread{
private static Logger LOGGER = Logger.getLogger(WindowsByThread.class);
private int TICKET = 1;
@Override
public void run(){
while (true) {
if (TICKET < 11) {
LOGGER.info(Thread.currentThread().getName() + "售出第" + TICKET + "张票");
TICKET++;
}
}
}
}
2,实现Runnable接口。创建一个实现了Runnable接口的类,用实现类去实现Runnable的抽象方法run(),创建该实现类的对象,将其当作参数传入到Thread类的构造器中,创建Thread类的对象,通过Thread类的对象调用start方法。
/**
* 实现Runnable接口
*/
class WindowsByRunnable implements Runnable{
// 票数
private int TICKET = 1;
private Logger LOGGER = Logger.getLogger(WindowsByRunnable.class);
private String name;
public WindowsByRunnable(String name){
this.name = name;
}
public void run(){
while (true) {
// 由于类中属性被多个线程共享,那么多个线程要操作同一个属性就可能出现资源同步的问题
// 使用同步代码块 关键字synchronized
// synchronized (this) {
if (TICKET < 11) {
LOGGER.info(Thread.currentThread().getName() + "售出第" + TICKET + "张票");
TICKET++;
} else {
break;
}
//}
}
}
}
3,实现callable接口。与实现Runnable的方式相比,callable的方法更加强大,call方法相比于run方法有返回值,可以抛异常,支持泛型的返回值。
步骤:首先创建一个实现了callable的实现类,实现call方法,将线程需要执行的操作写在call()方法中,创建callalbe的对象,将该接口对象传入到FutureTask容器中,创建FutureTask对象,再将FutureTask对象传入到Thread容器中创建Thread对象,并调用start()方法启动。
4,使用线程池。首先需要创建实现了Runnable或callable接口方式的对象,然后创建ThreadPoolExecutor的线程池,将创建好的实现了Runnable接口类的对象放入线程池中的执行类中的执行方法进行执行,最后需要关闭线程池。
// 使用了线程池的方法
private void sellByPool(){
int corePoolSize = 3;
int maximumPoolSize = 6;
long keepAliveTime = 60L;
TimeUnit unit = TimeUnit.SECONDS;
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize,
maximumPoolSize,
keepAliveTime,
unit,
new ArrayBlockingQueue<Runnable>(20));
// 预启动所有核心线程
executor.prestartAllCoreThreads();
for (int i=1; i < 3; i++) {
// 实例一个实现了Runnable的对象
WindowsByRunnable wbr = new WindowsByRunnable("售票窗口" + i);
executor.execute(wbr);
}
// 关闭线程池
executor.shutdown();
}
其中WindowsByRunnable类是一个实现了Runnable接口的实现类。