java22-50
Super 修饰方法和属性
package 1_package_super;
public class Person {
int age;
public void eat(){
System.out.println("I can eat");
}
}
package 1_package_super;
public class Student extends Person {
double scores;
public void study(){
System.out.println("I can study");
}
public void a(){
System.out.println(super.age); //super指的是父类,可以修饰属性
super.eat(); //可以修饰方法
//eat(); //super.可以省略不写(当子类和父类中属性和方法重名时,不写super.默认访问的时子类,若想调用父类的方法,则需要加上super.)
}
}
修饰构造器 平时写的空构造器都有super();,要调用父类的空构造器,只是一般省略不写。 所有构造器中第一行默认都有super();,一旦你的构造器中显示地使用了super调用了父类构造器的话,那么它的第一行就没有默认分配的super()。 在构造器中,super调用父类构造器和子类调用this构造器,只能选一个,两个不能共存,因为super修饰构造器和this修饰构造器都要放在第一行。 以后写代码构造器可以在Idea中快捷键生成alt+insert
package 1_package_super.1_package_super2;
public class Person {
int age;
String name;
public Person(){
super();
}
public Person(int age, String name){
this.age = age;
this.name = name;
}
}
package 1_package_super.1_package_super2;
public class Student extends Person {
double scores;
public Student(){
super(); //空构造器可以省略不写super
}
public Student(double scores){
super();
this.scores = scores;
}
public Student(int age, String name, double scores){
//super.age = age;
//super.name = name;
super(age, name); //利用super调用父类的参数
this.scores = scores;
}
}
package 1_package_super.1_package_super2;
public class Test {
public static void main(String[] args){
Student s = new Student();
}
}
package 1_package_super.1_package_super3;
public class Person {
String name;
int age;
public Person() { //尽量时刻保持空构造器存在
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
package 1_package_super.1_package_super3;
public class Student extends Person{
double height;
double weight;
public Student() {
}
public Student(String name, int age, double height, double weight) {
super(name, age);
this.height = height;
this.weight = weight;
}
}
ToString()方法
System.out.println(s.toString());//1_package_object.Student@1b6d3586
重写toString方法,快捷键alt+insert
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}
Equal()方法
判断内容是否一致,一般源码中object父类的方法不够用,需要子类进行重写
类和类产生关系
将一个类作为另一个类中的形参 一个类作为另一个类的属性
package 1_package_object.object3;
public class Boy {
//属性
int age;
String name;
//方法
public void buy(){
System.out.println("I can buy");
}
//构造器
public Boy() {
}
public Boy(int age, String name) {
this.age = age;
this.name = name;
}
}
package 1_package_object.object3;
public class Mom {
int age;
public void say(){
System.out.println("Mom like to say");
}
}
package 1_package_object.object3;
public class Girl {
String name;
double weight;
Mom m;
public Girl(String name, double weight) {
this.name = name;
this.weight = weight;
}
public void love(Boy b){ //类和类产生关系,将一个类作为另一个类中的形参
System.out.println("My boyfriend's name is:" + b.name + ", his age is:" + b.age);
b.buy();
}
public void listen(Mom m){
m.say();
}
public void wechat(){
m.say();
}
}
package 1_package_object.object3;
import 1_package_extend.Boss;
public class Test {
public static void main(String[] args){
Boy b = new Boy(30, "tom");
Boy b2 = new Boy(34, "tim");
Girl g = new Girl("sina", 45.45);
g.love(b2);
//通过一个类作为另一个类的形参调用
Mom mama = new Mom();
g.listen(mama);
//通过一个类作为另一个类的属性调用
g.m = new Mom();
g.wechat();
}
}
多态
多态针对方法,跟属性无关 多态:同一个行为,子类表现出不同的形态 同一个方法调用,由于对象的不同会产生不同的行为 为了提高代码的扩展性 多态的三个要素:继承,重写,父类引用指向子类对象Parent p = new Child();
多态的应用场合: 父类当作方法的形参,传入具体的子类对象 父类当作方法的返回值,返回的是子类的对象 接口当作方法的形参,传入具体的实现类的对象 接口当作方法的返回值,返回的是具体的实现类的对象
package 1_package_duotai;
public class Animal {
public void shout(){
System.out.println("我是小动物,我可以叫");
}
}
package 1_package_duotai;
public class Cat extends Animal{
public void shout(){
System.out.println("我是小猫,喵喵叫");
}
public void scratch(){
System.out.println("我是小猫,我会抓");
}
}
package 1_package_duotai;
public class Dog extends Animal{
public void shout(){
System.out.println("我是小狗,我可以汪汪叫");
}
public void guard(){
System.out.println("我是小狗,我可以保护主人");
}
}
package 1_package_duotai;
public class Pig extends Animal {
public void shout(){
System.out.println("我是小猪,我可以哼哼哼");
}
public void eat(){
System.out.println("我爱吃");
}
}
package 1_package_duotai;
public class Girl {
/*
public void play(Cat cat){ //类和类产生关系,将一个类作为另一个类的形参
cat.shout();
}
public void play(Dog dog){
dog.shout();
}
*/
public void play(Animal an){//将多个play提取成一个父类的方法
an.shout();
}
}
package 1_package_duotai;
public class Test {
public static void main(String[] args){
Cat c = new Cat();
Girl g = new Girl();
Dog d = new Dog();
Pig p = new Pig();
Animal an = p; //多态
g.play(an);
}
}
Pig p = new Pig();
Animal an = p;
将上面的代码合成一句话
Animal an = new Pig(); //父类引用指向子类对象
上面的代码是多态非常常见的应用场合:父类当方法的形参,然后传入的是具体的子类对象,
然后调用同一个方法,根据传入的子类的不同展现出来的效果也不同,构成了多态
package 1_package_duotai;
public class Demo {
public static void main(){
Pig p = new Pig();
Animal an = p; //向上转型
an.shout();
//将Animal类型转为Pig类型,向下转型
((Pig) an).eat();
((Pig) an).weight = 2.0;
}
}
多态的应用
工厂设计模式
package 1_package_duotai;
public class PetStore {
// 提供动物
public static Animal getAnimal(String petName){//把父类当成方法的返回值
Animal an = null;
if("猫".equals(petName)){ //petName.equals("猫")//这样写容易发生空指针
an = new Cat();
}
if("狗".equals(petName)){
an = new Dog();
}
if("猪".equals(petName)){
an = new Pig();
}
return an;
}
}
package 1_package_duotai;
public class Test {
public static void main(String[] args){
Cat c = new Cat();
Girl g = new Girl();
Dog d = new Dog();
// Pig p = new Pig();
//Animal an = p;
//Animal an = new Pig();
Animal an = PetStore.getAnimal("猫");
g.play(an);
}
}
多态的一个实际应用就是引用父类型的类类型指向子类对象~
(1)对于父子类都有的非静态方法来说,编译阶段调用父类版本,运行阶段
调用子类重写的版本(动态绑定)。
(2)对于父子类都有的静态方法来说,编译和运行阶段都调用父类版本。
public class Father {
public void say(){
System.out.println("father");
}
public static void action(){
System.out.println("爸爸打儿子!");
}
}
public class Son extends Father{
public void say() {
System.out.println("son");
}
public static void action(){
System.out.println("打打!");
}
public static void main(String[] args) {
Father f=new Son();
f.say();
f.action();
}
}
输出:son
爸爸打儿子!
当调用say方法执行的是Son的方法,也就是重写的say方法
而当调用action方法时,执行的是father的方法。
1.成员变量:编译和运行都参考左边。
2.成员函数(非静态):编译看左边,运行看右边
3.静态函数:编译和运行都看左边。
抽象类和抽象方法abstract
抽象类和抽象方法的关系:抽象类中可以定义n个抽象方法 作用:为子类提供一个通用的模板,子类可以在模板的基础上进行开发, 先重写父类的方法,然后可以扩展子类自己的内容。 抽象类的设计避免了子类设计的随意性,子类的设计变得更加严格,进行某些程度上的限制。 抽象类中一定有构造器,是为了给子类初始化对象,先要super调用父类的构造器。 抽象类不能被final修饰,因为抽象类设计的初衷就是为了给子类继承。
package 1_package_abstract;
//一个类中如果有方法是抽象方法,那么这个类也要变成抽象类
public abstract class Person {
public void eat(){
System.out.println("我喜欢吃");
}
//一个方法的方法体去掉,被abstract修饰,变成一个抽象方法
public abstract void say();
public abstract void sleep();
}
//抽象类可以被其他类继承
//一般子类不会加abstract修饰,一般会让子类重写父类中的抽象方法
class Student extends Person{
@Override
public void say() {
System.out.println("我是东北人。喜欢说话");
}
@Override
public void sleep(){
System.out.println("我喜欢睡觉");
}
}
//
class Demo{
public static void main(String[] args){
//Person p = new Person();//抽象类不能被创建对象
Student s = new Student();
s.say();
s.sleep();
}
}
接口interface
类是类,接口是接口,它们是同一层次的概念。 接口中没有构造器。 接口声明:interface。 Jdk1.8之前,接口中只有2部分内容: 1.常量:public static final 2.抽象方法: public abstract(接口中的方法都是抽象方法)
Jdk1.8之后,新增非抽象方法: 1.被public default修饰的抽象方法 注意:default修饰符必须要加上,实现类中要是想重写接口中的非抽象方法,那么default修饰符必须不能加 2.静态方法:静态方法不能重写
实现implements 类和接口的关系,实现关系,类实现接口. 一旦实现一个接口,那么实现类要重写接口中的抽象方法. java只有单继承,java还有多实现, 一个类继承其他类,只能继承一个父类 实现类实现接口的话,可以实现多个接口
//先继承,再实现
abstract class Studnet extends Person implements TestInterface01,TestInterface02{
接口的作用:定义规则
package 1_package_interface;
import 1_package1.Person;
import 1_package2.Test;
public interface TestInterface01 {
//修饰符可以省略不写,idea会自动补全
public static final int NUM = 10;
public abstract void a();
public abstract void b(int num);
public abstract int c(String name);
//类和接口的关系,实现关系:类实现接口
}
interface TestInterface02 {
void e();
void f();
}
//一旦实现一个接口,那么实现类要重写接口中的抽象方法
//java只有单继承,java还有多实现,一个类继承其他类,只能继承一个父类
//实现类实现接口的话,可以实现多个接口
//先继承,再实现
class Student extends Person implements TestInterface01,TestInterface02{
@Override
public void a(){
}
@Override
public void b(int num){}
@Override
public int c(String name){
return 1000;
}
@Override
public void e(){}
@Override
public void f(){}
}
class T{
public static void main(String[] args) {
//TestInterface02 t = new TestInterface02();//接口不能创建对象
TestInterface02 t = new Student(); //接口指向实现类,多态的体现
//接口中常量的访问
System.out.println(TestInterface01.NUM);
System.out.println(Student.NUM);
Student s = new Student();
System.out.println(s.NUM);
TestInterface01 t2 = new Student();
System.out.println(t2.NUM);
}
}
Jdk1.8之后 如果接口中只有抽象方法,那么实现类会受很大影响,接口中只要新增一个抽象方法,实现类就得重写该方法 接口中加入非抽象方法后,就能避免这个问题
package 1_package_interface;
public interface TestInterface2 {
//常量
public static final int NUM = 10;
//抽象方法
public abstract void a();
//非抽象方法,这里的default不能省略
public default void b(){
System.out.println("接口中的default方法");
}
//静态方法
public static void c(){
System.out.println("接口中的静态方法");
}
}
class Demo implements TestInterface2{
@Override
//这里重写接口中的方法时不能加default
public void a(){
System.out.println("重写了a方法");
}
public static void c(){
System.out.println("Demo中的静态方法");
}
}
class A{
public static void main(String[] args){
Demo d = new Demo();
d.c();//这里执行的是Demo中的静态方法
Demo.c();//这里跟上面两行是一样的,不过静态方法更推荐这种调用方式
TestInterface2.c();
}
}
内部类外部类
类的组成:属性,方法,构造器,代码块(普通块,静态块,构造块,同步块),内部类 一个类中包含的类叫内部类 内部类:成员内部类(里面有属性,方法,构造器等)和局部内部类(位置:方法内,块内,构造器类)
package 1_package_neibulei;
public class TestOuter {
//成员内部类
class D{
int age = 20;
String name;
public void f(){
//内部类可以访问外部类的方法属性
System.out.println(age);
a();
int age = 30;
System.out.println(age);
System.out.println(this.age);
System.out.println(TestOuter.age);
}
}
//静态内部类
static class E{
public void method(){
System.out.println(age);
// a(); 这里不能访问a()方法,因为a方法不是static的
}
}
//属性
static int age = 10;
//方法
public void a(){
//外部类想要访问内类的属性,需要先创建对象
D d = new D();
System.out.println(d.name);
System.out.println("这是a方法");
{
System.out.println("这是一个普通块");
class b{}
}
class a{}
}
static {
System.out.println("这是一个静态块");
}
{
System.out.println("这是构造块");
}
//构造器
public TestOuter() {
System.out.println("这是构造器");
class c{}
}
public TestOuter(int age) {
this.age = age;
}
}
成员内部类
package 1_package_neibulei;
public class TestOuter2 {
public void method(){
//在局部内部类中访问的属性必须是final修饰的
final int num = 10;
class A{
public void a(){
//num = 20;
System.out.println(num);
}
}
}
//如果类B在整个项目中只使用一次,那么就没有必要单独创建一个B类,使用一个内部类就可以了
public Comparable method2(){
class B implements Comparable{
@Override
public int compareTo(Object o){
return 100;
}
}
return new B();
}
public Comparable method3(){
//匿名内部类
return new Comparable() {
@Override
public int compareTo(Object o) {
return 0;
}
};
}
public void test(){
Comparable com = new Comparable() {
@Override
public int compareTo(Object o) {
return 0;
}
};
}
}
匿名类
匿名类通常用来继承一个父类或者实现一个接口,它没有构造器,不能被引用 匿名内部类是一个表达式,在定义的时候就用new关键字实例化了,可以直接使用 包含: 1.花括号{}:声明主体 2.以分号;结束 3.一对括号,实现接口则是空括号,继承类则是有参数要括号里带上参数 4.new操作符 5.实现接口,继承类
匿名类实现接口
package 1_package_niminglei;
public class Hello {
//定义一个接口
interface HelloWorld{
public abstract void greet();
public abstract void greetSomeone(String name);
}
//定义一个方法
public void sayHello(){
//定义一个局部类greet1,实现了接口
class Greet1 implements HelloWorld{
String name = "world1";
@Override
public void greet(){
greetSomeone("world1");
}
@Override
public void greetSomeone(String someone){
name = someone;
System.out.println("hello1" + name);
}
}
//匿名类实现接口
HelloWorld g2 = new HelloWorld() {
String name = "world2";
@Override
public void greet() {
greetSomeone("world2");
}
@Override
public void greetSomeone(String someone ){
name = someone;
System.out.println("hello2" + name);
}
};
HelloWorld g1 = new Greet1();
g1.greet();//g1是一个普通内部类,使用时需要先实例化
g2.greet();//g2是一个匿名内部类,直接使用
}
public static void main(String... args){
Hello h = new Hello();
((Hello) h).sayHello();
}
}
匿名类继承父类
package 1_package_niminglei;
public class AnimalTest {
private final String ANIMAL = "动物";
public void accessTest(){
System.out.println("匿名内部类访问外部方法");
}
class Animal{
private String name;
public Animal(String name){
this.name = name;
}
public void printAnimalName(){
System.out.println(bird.name);
}
}
//鸟类,匿名类,继承父类Animal,可以重写父类方法
Animal bird = new Animal("布谷鸟"){
@Override
public void printAnimalName(){
accessTest();//访问外部类成员
System.out.println(ANIMAL);//访问外部类final修饰的变量
super.printAnimalName();
}
};
public void print(){
bird.printAnimalName();
}
public static void main(String[] args){
AnimalTest a = new AnimalTest();
a.print();
}
}
异常Exception
if-else处理异常缺点太多
package 1_package_exception;
import java.util.Scanner;
public class Test {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
System.out.println("请录入第一个数:");
if(sc.hasNextInt()){
int num1 = sc.nextInt();
System.out.println("请录入第二个数:");
if(sc.hasNextInt()){
int num2 = sc.nextInt();
if(num2 == 0){
System.out.println("对不起,除数不能为0");
}else{
System.out.println("商:" + num1/num2);
}
}else {
System.out.println("录入的不是int类型");
}
}else {
System.out.println("录入的不是int类型");
}
}
}
Try-catch-finally
把可能出现异常的代码放入try{}代码块中,然后将异常封装为对象,被catch后面的()中的那个异常对象接收, 接收以后,执行catch后面{}的代码,然后try-catch后面的而代码该怎么执行就怎么执行 try{
}
catch(Exception ex){
}
1)try中没有异常,catch中代码不执行, 2)try中有异常,catch进行捕获,try中出错后面的代码不会执行 如果遇到的异常和你出错的异常是匹配的,走catch代码 如果不匹配,不走catch中的代码,程序遇到异常,则会中断,后续代码不执行
package 1_package_exception;
import java.util.Scanner;
public class Test2 {
public static void main(String[] args) {
try {
Scanner sc = new Scanner(System.in);
System.out.println("请录入第一个数:");
int num1 = sc.nextInt();
System.out.println("请录入第二个数:");
int num2 = sc.nextInt();
System.out.println("商:" + num1 / num2);
}catch (Exception ex){
System.out.println("对不起,程序出现了异常");
}
System.out.println("———谢谢你使用计算器———");
}
}
package 1_package_exception;
import java.util.Scanner;
public class Test3 {
public static void main(String[] args) {
try {
Scanner sc = new Scanner(System.in);
System.out.println("请录入第一个数:");
int num1 = sc.nextInt();
System.out.println("请录入第二个数:");
int num2 = sc.nextInt();
System.out.println("商:" + num1 / num2);
}catch (Exception ex){
//第一种处理方式:什么都不写
//第二种处理方式,给出提示
//System.out.println("对不起,程序出现了异常");
//第三种处理方式,打印异常:
//1)调用toString()方法,显示异常的类名
//System.out.println(ex);
//System.out.println(ex.toString());
//2)显示异常信息对应的字符串,没有就显示null
//System.out.println(ex.getMessage());
//3)将异常信息捕获后,在控制台展示出来,方便查看(比较常用的方法)
//ex.printStackTrace();
//第四种处理方式,抛出异常
throw ex;
}
System.out.println("———谢谢你使用计算器———");
}
}
将代码放在finally中,无论啥报错都会执行 遇到try中有return的,先执行finally,再执行return 什么代码会放在finally中:关闭数据库资源,关闭IO流,关闭socket资源 当有System.exit(1);时,finally中的代码不执行
package 1_package_exception;
import java.util.Scanner;
public class Test3 {
public static void main(String[] args) {
try {
Scanner sc = new Scanner(System.in);
System.out.println("请录入第一个数:");
int num1 = sc.nextInt();
System.out.println("请录入第二个数:");
int num2 = sc.nextInt();
System.out.println("商:" + num1 / num2);
System.exit(1);
return;
}catch (Exception ex){
throw ex;
}finally {
System.out.println("———谢谢你使用计算器———");
}
}
}
try中出现异常后,将异常的类型跟catch中的类型依次进行比较, 按照后面的代码顺序进行比对,执行第一个与异常类型匹配的catch类型。 一旦执行一条catch语句之后,后面的catch语句就会被忽略。 一般会将特殊异常放在前面,一般异常放在后面catch(Exception ex){}。也就是先写子类异常,再写父类异常。 在jdk1.7之后,catch后面的括号里的异常可以并列显示
package 1_package_exception;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Test3 {
public static void main(String[] args) {
try {
Scanner sc = new Scanner(System.in);
System.out.println("请录入第一个数:");
int num1 = sc.nextInt();
System.out.println("请录入第二个数:");
int num2 = sc.nextInt();
System.out.println("商:" + num1 / num2);
}catch (InputMismatchException ex){
System.out.println("录入的不是int");
}catch (ArithmeticException ex){
System.out.println("除数不能为0");
}catch(EnumConstantNotPresentException | ExceptionInInitializerError ex){
}
catch(Exception ex){
System.out.println("其他异常");
}
finally {
System.out.println("———谢谢你使用计算器———");
}
}
}
exception:
运行时异常
:运行起来发生的异常
package 1_package_exception;
public class Test5 {
public static void main(String[] args) {
int[] arr = {1, 2, 3};
System.out.println(arr.length);
int[] arr2 = null;
//System.out.println(arr2.length);//Exception in thread "main" java.lang.NullPointerException
// System.out.println(arr[10]);//Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
}
}
检查异常
: Alt + enter
public class Test6 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Class.forName("").newInstance();
}
}
throw和throws的区别:
位置不同: throw在方法内部 throws在方法声明的地方 内容不同: Throw+异常对象(运行时检查异常) Throws+异常类型(可以多个类型用逗号拼接) 作用不同 throw:异常出现的源头,制造异常 throws:在方法声明处,告诉方法调用者,这个方法可能出现的异常,然后调用者再自己处理这个异常
package 1_package_exception;
import java.util.Scanner;
public class Test7 {
public static void main(String[] args) throws Exception {
/*
try {
devide();
} catch (Exception e) {
e.printStackTrace();
}
*/
devide();
}
public static void devide() throws Exception {
//实现一个功能:两个数相除,当除数为0的时候,出现异常
Scanner sc = new Scanner(System.in);
System.out.println("请录入第一个数:");
int num1 = sc.nextInt();
System.out.println("请录入第二个数:");
int num2 = sc.nextInt();
if(num2 == 0){//除数为0,制造异常
//制造运行时异常
//throw new RuntimeException();
throw new Exception();
}else {
System.out.println("商:" + num1 / num2);
}
}
}
异常-重载 重载中异常不受影响 package 1_package_exception;
public class Demo { public void a() throws Exception{
}
public void a(int age)throws Exception{
}
}
异常-继承
子类父类,父类的异常必须是子类异常的父类 Exception是其他异常的父类
package 1_package_exception.test;
public class Person {
public void eat() throws RuntimeException{
}
}
package 1_package_exception.test;
public class Student extends Person {
public void eat() throws Exception{
}
}
自定义异常
自定义的异常可以继承运行时异常,也可以继承检查异常
package 1_package_exception;
public class MyException extends Exception{
static final long serialVersionUID = -7034897190745766939L;
public MyException() {
}
public MyException(String msg){
super(msg);
}
}
包装类
将基本数据类型进行了一个封装,产生一个新的类-->包装类 包装类属于引用数据类型 基本数据类型-包装类-继承自 byte-Byte-Number-Object short-Short-Number-Object int-Integer-Number-Object long-Long-Number-Object float-Float-Number-Object double-Double-Number-Object char-Character-Object boolean-Boolean-Object
Integer类
继承自lang包 实现自comparable接口
public final class Integer extends Number implements Comparable<Integer> {
package 1_package_common_class;
public class Test1 {
public static void main(String[] args) {
//属性
System.out.println(Integer.MAX_VALUE);//2147483647
System.out.println(Integer.MIN_VALUE);//-2147483648
System.out.println(Integer.MAX_VALUE+1);//-2147483648
System.out.println(Integer.MIN_VALUE-1);//2147483647
}
}
构造器
public Integer(int value) {
this.value = value;
}
public Integer(String s) throws NumberFormatException {
this.value = parseInt(s, 10);
}
package 1_package_common_class;
public class Test2 {
public static void main(String[] args) {
Integer i = new Integer(12);
System.out.println(i.toString());
Integer e = new Integer("1qeqe");
System.out.println(e.toString());
}
}
装箱拆箱
package 1_package_common_class;
public class Test3 {
public static void main(String[] args) {
//自动装箱,将int类型转为integer类型
Integer i = 12;
System.out.println(i);
//自动拆箱,integer转为int
Integer i2 = new Integer(12);
int num = i2;
System.out.println(num);
}
}
Integer a = 10; // 自动装箱 int b = a; // 自动拆箱
自动装箱:
基本类型的数据处于需要对象的环境中时,会自动转为“对象”。
我们以Integer为例:
Integer i = 5
编译器会自动转成:Integer i = Integer.valueOf(5),这就是Java的自动装箱。
Integer i = 100;//自动装箱
//相当于编译器自动为您作以下的语法编译:
Integer i = Integer.valueOf(100);//调用的是valueOf(100),而不是new Integer(100)
自动拆箱:
每当需要一个值时,对象会自动转成基本数据类型,没必要再去显式调用intValue()、doubleValue()等转型方法。
Integer i = Integer.valueOf(5);
int j = i;
编译器会自动转成:int j = i.intValue();
这样的过程就是自动拆箱。
自动装箱/拆箱的本质是:
自动装箱与拆箱的功能是编译器来帮忙,编译器在编译时依据您所编写的语法,决定是否进行装箱或拆箱动作。
Integer i = 100;
int j = i;//自动拆箱
//相当于编译器自动为您作以下的语法编译:
int j = i.intValue();
package 1_package_common_class;
public class Test4 {
public static void main(String[] args) {
//compareTo
Integer i1 = new Integer(12);
Integer i2 = new Integer(12);
///return (x < y) ? -1 : ((x == y) ? 0 : 1);
System.out.println(i1.compareTo(i2));//0
//equals
Integer i3 = new Integer(12);
Integer i4 = new Integer(12);
System.out.println(i3 == i4);//false比较的是地址,永远是false
boolean flag = i3.equals(i4);//true
System.out.println(flag);
//integer对象通过自动装箱来完成
Integer i5 = 130;
Integer i6 = 130;
System.out.println(i5.equals(i6));//true
System.out.println(i5 == i6);//false
//如果比较的值在-128到127之间,那么比较的是两个值的大小,
// 如果不在这个范围内,那么比较的就是对象的地址
}
}
• 自动装箱调用的是valueOf()方法,而不是new Integer()方法。
• 自动拆箱调用的xxxValue()方法。
• 包装类在自动装箱时为了提高效率,对于-128~127之间的值会进行缓存处理。超过范围后,对象之间不能再使用==进行数值的比较,而是使用equals方法。