Object类和内部类
一、Object类
JDK类库的根类:Object,任何一个类默认继承或者间接继承Object。
jdkAPI:应用程序编程接口 (Application Program Interface)
API就是jdk的类库,每一个API都会配置好一套API帮助文档
int hashCode()
将对象的内存地址转换成一个整数,哈希值
这个哈希值只是人为的标记的每个对象的内存地址编号,有重复的可能,而真正的内存是不可能重复的。
String toString()
将对象转换为字符串形式,类的位置+@+16进制无符号哈希值
直接输出一个对象,默认调用tostring()方法
getClass().getName() + '@' + Integer.toHexString(hashCode())
com.szwollf.Day11.DemotoString.DemotoString@4554617c
实际应用中,我们希望返回值是一串字符串,而不是地址@哈希值,
所以我们要重写toString()方法,把对象的成员变量以字符串形式输出。
源码中boolean equals(Object obj)等价于==,比较的是内存地址,和toString一样,我们希望比较的是String的字面值,而不是内存地址
所以我们要重写equals方法,比较对象输出的的字面值
finalize()方法
这个方法是protected修饰的,在Object类中这个方法的源代码是:
protected void finalize() throws Throwable
垃圾回收特点:
(1) 当对象不再被程序使用时,垃圾回收器将会将其回收
(2) 垃圾回收是在后台运行的,我们无法命令垃圾回收器马上回收资源,但是我们可以告诉他,尽快回收资源(System.gc 和 Runtime.getRuntime().gc())
(3) 垃圾回收器在回收某个对象的时候,首先会调用该对象的 finalize 方法
(4) GC 主要针对堆内存
finalize()回收垃圾之前的标志性的方法,只要这个方法执行了,意味着垃圾就回收了
-
== 和equals()的区别?
== 可以比较基本数据类型,可以比较引用数据类型
equals(Object obj)只能比较引用数据类型
String类中的equals()比较的是 字符串的字面值,因为String是sun公司写的,已经重写了toString()
二、String类的两种写法
语法:
-
String s=" "
-
String s=new String(" ")

package com.szwollf.Day11.DemotoString; public class Demo2Test { public static void main(String[] args) { String s1="sz07"; String s2="sz07"; String s3=new String("sz07"); String s4 = new String("sz07"); System.out.println(s1==s2);//==代表比较内存地址,String类型都在同一个地址的常量池 System.out.println(s1==s3); System.out.println(s3==s4); System.out.println("======================="); System.out.println(s1.equals(s2));//String类的equals方法都被重写了,比较的是字面值,所以这三个全是true System.out.println(s1.equals(s3)); System.out.println(s3.equals(s4)); Demo2 s5=new Demo2(); Demo2 s6=new Demo2(); System.out.println("======================="); System.out.println(s1.equals(s5));//前三个都是不同类new的对象,所以肯定不一样 System.out.println(s2.equals(s5)); System.out.println(s3.equals(s5)); System.out.println(s6.equals(s5));//这里是自己写的,没有重写equals方法,所以比较的是内存地址 System.out.println("=========================="); String s7="sz"; String s8="07"; String s9=s7+s8; String s10 = "sz" + "07";//等价于s10="sz07" String s11 = s7 + "07";//只要有一个变量进行拼接,就不会进入常量池 String s12 = "sz" + "0"+"7"; System.out.println(s9); System.out.println(s1.equals(s9)); System.out.println(s1==s9);//false System.out.println(s1==s10); System.out.println(s1.equals(s10)); System.out.println("=============================="); System.out.println(s1.equals(s11)); System.out.println(s1==s11);//false System.out.println(s1==s12);//true } }
总结:
只要有一个变量形式的字符串相加相当于new
全部都是字面值拼接才会在常量池创建
三、内部类(了解)
实例内部类
package com.szwollf.Day11.DemoInnerclass; public class OuterClass { private int pi1; int i1; public void info(){ //System.out.println(i2);//i2为内部类的局部变量,外部类无法访问 System.out.println("外部类info....."); } //内部类 public class InnerClass{ private int pi2; int i2; public void info2(){ System.out.println(pi1);//外部类的成员变量在整个外部类里都可以调用 OuterClass.this.info();//省略的类名.this System.out.println("内部类的info2方法...."); } } } package com.szwollf.Day11.DemoInnerclass; public class TestOuterClass { public static void main(String[] args) { //调用内部类的成员 OuterClass.InnerClass inner=new OuterClass().new InnerClass(); inner.info2(); System.out.println(inner.i2);//内部类的对象才可以调用内部类的变量 } }
实例内部类:
内部类可以直接使用外部类的成员变量和成员方法----省略的是 外部类名.this
外部类可以通过创建对象来使用内部的成员变量和成员方法
外部类.内部类 变量名=new 外部类().new 内部类();
静态内部类:
package com.szwollf.Day11.StaticInnerClass; public class Outer { int i1; static int si1; public void outFun1() { System.out.println(InnerClasses.si2); InnerClasses.innerFun2(); // InnerClasses.innerFun1();//错误,因为没有new对象,不能调用成员方法 InnerClasses ic=new InnerClasses(); ic.innerFun1(); System.out.println("outfun1...."); } public static void outFun2() { System.out.println(InnerClasses.si2); // InnerClasses.innerFun2(); // InnerClasses.innerFun1(); // InnerClasses ic=new InnerClasses(); // ic.innerFun1(); System.out.println("outfun2...."); } //static可以修饰内部类 public static class InnerClasses { int i2; static int si2; public void innerFun1() { // System.out.println(i1); //错误的 System.out.println(si1); System.out.println(i2); // outFun1(); 错误的 outFun2(); System.out.println("innerfun1...."); System.out.println(si2); } public static void innerFun2() { System.out.println(si1); outFun2(); // outFun1(); System.out.println("innerfun2...."); System.out.println(si2); // innerFun2(); } } } package com.szwollf.Day11.StaticInnerClass; public class Test { public static void main(String[] args) { Outer o1=new Outer(); System.out.println(o1.i1); o1.outFun1(); } }
静态内部类:
静态内部类,不管是在静态方法中,还是非静态方法中,只能调用外部类的静态成员
外部类,能够直接调用静态内部类的静态成员---- 类名.属性/方法()
静态内部类的非静态成员,创建对象来调用---外部类.内部类 变量名=new 外部类.内部类();
-
局部内部类
package com.szwollf.Day11.LocalClass; public class Outer { int i1; int i2; public void outFun1(){ System.out.println("outFun1..."); } public void outFun2(){ //写一个类 //局部内部类不能用public修饰,局部类只能在局部使用,无法公开,无法在外部new对象, class InnerClasses{ int i3; int i4; public void innerFun3(){ System.out.println(i1); System.out.println(i3); outFun1(); //outFun2(); innerFun4(); System.out.println("innerFun3。。。"); } public void innerFun4(){ System.out.println("innerFun4.。。"); } } //创建对象 InnerClasses inner=new InnerClasses(); System.out.println(inner.i3); inner.innerFun4(); inner.innerFun3(); } } package com.szwollf.Day11.LocalClass; public class Test { public static void main(String[] args) { Outer out=new Outer(); out.outFun2(); } }
局部内部类:类在方法中或者代码块中
局部内部类可以直接使用外部类的成员
外部类不能使用内部类的成员
内部类的成员只能在局部去创建对象使用成员
匿名函数(掌握)
package com.szwollf.Day11.AnonymityClass; public interface Anonymity { int a=2; void fun(); } package com.szwollf.Day11.AnonymityClass; public class Test { public static void main(String[] args) { Anonymity am=new Anonymity() { @Override public void fun() { System.out.println("匿名函数重写"); } }; am.fun(); } }
匿名函数就是在创建对象时,不用重新写类重写方法,直接在new完对象后直接写个无名类体重写,因为主要是便于重写,所以通常用于接口重写和抽象类的抽象方法实现


浙公网安备 33010602011771号