一、装箱拆箱
1、封装类
所有的基本类型,都有其对应的类类型
例如 整型 int 的类类型就是 Integer
这种类就叫做封装类
package digit;
public class TestNumber {
public static String getType(Object o){
return o.getClass().toString();}
public static void main(String[] args) {
int i = 5;
//吧一个基本类型的变量,转换为Integer对象
Integer it = new Integer(i); //含参数的构造函数,参数为已知基本变量
//把一个Integer对象,转换为一个基本类型的int
int i2 = it.intValue();
}
}
//(1)intValue()是java.lang.Number类的方法,Number是一个抽象类。Java中所有的数值类都继承它。 // 也就是说,不但是Integer有该方法,Double,Long都有 //(2)此方法的意思:输出int数据。每个数值类中具体的实现是不同的。 // 例如Float类和Double类的intValue方法,就是丢掉了小数位,
2、Number类
数字封装类有:
Byte,Short,Integer,Long,Float,Double
这些类都是抽象类Number的子类
package digit;
public class TestNumber {
public static void main(String[] args) {
int i = 5;
Integer it = new Integer(i);
//Integer是Number的子类,所以打印true
System.out.println(it instanceof Number);
}
}
3、基本类型转封装类
Integer it = new Integer(i);
是含参数的构造函数,将基本类型的 变量i转换为封装类型的Integer
4、封装类转基本类型
int i2 = it.intValue();
需要已经转换为封装类型了,才有意义。封装类型的对象,调用intValue方法。
5、自动装箱
不需要调用构造方法,仅仅利用 = 号,就完成了基本类型转封装类型。
成为 装箱
Integer it = new Integer(i);
(这个是调用了构造方法)
Integer i3 = i;
(这里就是自动装箱,没有使用构造方法。)
6、自动拆箱
没有调用intValue方法,仅仅使用 = 号就完成了封装类型转换基本类型。
就叫 拆箱。
int i = 5;
Integer it = new Integer(i);
//封装类型转换成基本类型
int i2 = it.intValue();
//自动转换就叫拆箱
int i3 = it;
7、int 的最大值、最小值
可以通过查看 Integer的最大最小值得到
package digit;
public class TestNumber {
public static void main(String[] args) {
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
}
}
8、练习
1. 对byte,short,float,double进行自动拆箱和自动装箱
2. byte和Integer之间能否进行自动拆箱和自动装箱
3. 通过Byte获取byte的最大值
package digit;
public class TestFengZhuang {
public static void main(String[] args) {
int i = 5;
byte a = 15;
short b = 19;
float c = 3.156f; //为什么不能写3.156,因系统默认为double,所以末尾要加f
double d = 6.125;
//基本类型转换为封装类型
Integer i1 =i;
Byte a1 = a;
Short b1 = b;
Float c1 =c;
Double d1 = d;
//自动拆箱
byte a2 = a1;
short b2 =b1;
float c2 =c1;
double d2 = d1;
}
}
2、
不能实现自动装箱
System.out.println(Byte.MAX_VALUE);
System.out.println(Byte.MIN_VALUE);
二、字符串转换
1、数字转字符串
(1)直接使用String类的静态方法.valueOf()。
(2)先将整型i,自动装箱为Integer,再使用其方法.toString();
package digit;
public class TestNumber {
public static void main(String[] args) {
int i = 5;
//方法1
String str = String.valueOf(i);//String类的静态方法valueOf
//方法2
Integer it = i;//自动装箱 为 Integer类型
String str2 = it.toString();
}
}
String.valueOf(i)
就是将基本类型i转换为字符串类型
来看一个JAVA的面试题:关于ValueOf的取值问题
package com.javaexe;
public class AboutValueOf {
public static void main(String[] args) {
Integer n = new Integer(1);
Integer m = new Integer(1);
System.out.println(n == m);
Integer n1 = Integer.valueOf(1);
Integer m1 = Integer.valueOf(1);
System.out.println(n1 == m1);
Integer n2 = 128;
Integer m2 = 128;
System.out.println(n2 == m2);
}
}
判断输出的结果,并分析!
(1)第一个很好理解,虽然参数都是整型 1 ,但是这里是利用构造方法,实例化了对象。因此,两个指向对象的引用n和m,就具有不同的地址,判断为 false;
(2)我们先看第三个,使用了自动装箱,将整型数据128,转换为Integer封装类型。看似没有问题,为什么不对呢?
(3)回到第二个,实际上自动装箱也就是使用.valueOf()方法。二三的性质一致。主要原因在于该方法上。我们查看封装类Integer,发现
我们可以看见在装箱时Integer的valueOf(int)方法。而在拆箱的时候自动调用的是Integer的intValue方法
可以看见该方法是具有条件的,当i的值不超过限制时,就会正常输出数据值,否则会实例化一个对象。
那么,这个条件范围是多少呢?
源码中显示,high为127,low为-128。
综上,二中的装箱 数据1 在范围内,所以不会实例化对象,判断的是两个数据1 是否相等,结果为true
三中的 数据128 已经超出的数据范围,所以会实例化对象,这里判断的就是两个不同对象的地址,结果为 false。
toString()方法
封装类型转为字符串是可以调用该方法,但是只有封装类型可以。
2、字符串转数字
调用Integer的静态方法parseInt
package digit;
public class TestNumber {
public static void main(String[] args) {
String str = "999";
int a = 1;
int i = Integer.parseInt(str);
System.out.println(i);
System.out.println(a + i);
}
}
parseInt可将字符串转换为整型数据,但前提是,原字符串就是数据的样子
3、练习
参考上述步骤
把浮点数 3.14 转换为 字符串 "3.14"
再把字符串 “3.14” 转换为 浮点数 3.14
如果字符串是 3.1a4,转换为浮点数会得到什么?
package digit;
public class TestNumber {
public static void main(String[] args) {
float i = 3.14f;
//转换字符串类型
String str1 = String.valueOf(i);
System.out.println(str1);
Float i1 = i;//自动装箱
String str2 = i1.toString();
System.out.println(str2);
//字符串转浮点数
float f =Float.parseFloat(str2);
System.out.println(f);
//3.1a4
String s = "3.1a4";
//float f1 = Float.parseFloat(s);
}
}
三、数学方法
java.lang.Math提供了一些常用的数学运算方法,并且都是以静态方法的形式存在
package digit;
public class TestNumber {
public static void main(String[] args) {
float f1 = 5.4f;
float f2 = 5.5f;
//5.4四舍五入即5
System.out.println(Math.round(f1));
//5.5四舍五入即6
System.out.println(Math.round(f2));
//得到一个0-1之间的随机浮点数(取不到1)
System.out.println(Math.random());
//得到一个0-10之间的随机整数 (取不到10)
System.out.println((int)( Math.random()*10));
//开方
System.out.println(Math.sqrt(9));
//次方(2的4次方)
System.out.println(Math.pow(2,4));
//π
System.out.println(Math.PI);
//自然常数
System.out.println(Math.E);
}
}
2、练习
统计找出一千万以内,一共有多少质数
质数概念: 只能被1和自己整除的数
举例:
5只能被 1和5整除,所以是质数
8可以被2整除,所以不是质数
package digit;
import static java.lang.Math.*;
public class TestNumber {
public static void main(String[] args) {
double max_n = 10_000_000;//一千万
double min_n = 1/max_n;//一千万分之一
double ans = pow(1+min_n,max_n);
System.out.println(ans);
System.out.println(ans - E);
//1千万以内的素数个数
int sum_su = 0;
for (int i = 2; i < max_n; i++) {
boolean flag = true;//标志
for (int j = 2; j <= sqrt(i); j++) {//找最小的因数
if( i%j==0 ){
flag = false;
break;
}
}
if(flag) sum_su++;
}
System.out.println("1千万以内的素数个数 = "+sum_su);
}
}
四、格式化输出
1、格式化输出
如果不适用格式化输出,在变量比较多的情况下,就需要使用字符串拼接。会显得十分繁琐
使用了格式化输出,简洁明了。
%s 表示字符
%d 表示数字
%n 表示换行。
package digit;
import static java.lang.Math.*;
public class TestNumber {
public static void main(String[] args) {
String name = "盖伦";
int kill = 8;
String title = "超神";
//直接使用+号连接,编码繁琐维护性差
System.out.println(name + "在进行了连续"+ kill +"次击杀,获得了"+title+"称号\n");
//使用格式化输出
String sentenceFormat = "%s在进行了连续%d次击杀,获得了%s称号!%n";
System.out.printf(sentenceFormat,name,kill,title);
}
}
格式化输出还是需要两步,一步设置字符串,一步打印相应内容。
2、printf和format
printf和format能够达到一模一样的效果
如何通过eclipse查看java源代码 可以看到,在printf中直接调用了format
两个参数,第一个为格式化输出句子,第二个为相对应变量
package digit;
import static java.lang.Math.*;
public class TestNumber {
public static void main(String[] args) {
String name = "盖伦";
int kill = 8;
String title = "超神";
//使用格式化输出
String sentenceFormat = "%s在进行了连续%d次击杀,获得了%s称号!%n";
System.out.printf(sentenceFormat,name,kill,title);
System.out.format(sentenceFormat,name,kill,title);
}
}
得到的结果一样。
3、换行符
JAVA可以多平台使用,但是为避免错误,使用%n
package digit;
import static java.lang.Math.*;
public class TestNumber {
public static void main(String[] args) {
String name = "盖伦";
int kill = 8;
String title = "超神";
//使用格式化输出
System.out.printf("这是换行符%n11");
System.out.printf("这是换行符%n");
}
}
4、总长度,左对齐,补0,千位分隔符,小数点位数,本地化表达
package digit;
import java.util.Locale;
public class TestNumber {
public static void main(String[] args) {
int year = 2020;
//总长度,左对齐,补0,千位分隔符,小数点位数,本地化表达
//直接打印数字
System.out.format("%d%n",year);
//总长度是8,默认右对齐
System.out.format("%8d%n",year);
//总长度是8,左对齐
System.out.format("%-8d%n",year);
//总长度是8,不够补0
System.out.format("%08d%n",year);
//千位分隔符
System.out.format("%,8d%n",year*10000);
//小数点位数
System.out.format("%.2f%n",Math.PI);
//不同国家的千位分隔符
System.out.format(Locale.FRANCE,"%,.2f%n",Math.PI*10000);
System.out.format(Locale.US,"%,.2f%n",Math.PI*10000);
System.out.format(Locale.UK,"%,.2f%n",Math.PI*10000);
}
}
5、练习
package digit;
import java.util.Scanner;
public class TestNumber {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("请输入地名:");
String a = s.nextLine();
System.out.println("请输入公司类型:");
String b = s.nextLine();
System.out.println("请输入老板名字:");
String c = s.nextLine();
System.out.println("请输入金额:");
String d = s.nextLine();
System.out.println("请输入产品:");
String e = s.nextLine();
System.out.println("请输入价格计量单位:");
String f = s.nextLine();
String sentenceFormat ="%s最大的%s倒闭了,王八蛋老板%s吃喝嫖赌,欠下了%s个亿," +
"带着他的小姨子跑了!我们没有办法,拿着%s抵工资!原价都是一%s多、两%s多、三%s多的%s," +
"现在全部只卖二十块,统统只要二十块!%s王八蛋,你不是人!我们辛辛苦苦给你干了大半年,你不发工资,你还我血汗钱,还我血汗钱! ";
System.out.format(sentenceFormat,a,b,c,d,e,f,f,f,e
,c);
}
}