欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java基础语法之类和对象理解

程序员文章站 2022-07-10 19:10:56
常用类内部类编译之后可生成独立的字节码文件。内部类可以直接访问外部的属性和方法。1。成员内部类:在类的内部定义,与实例方法和实例属性同级。创建内部类,必须依赖外部对象。创建方式:1.Outer out=new Outer();Outer.Inner in=out.new Inner();2.Outer.Inner in=new Outer.new Inner();成员内部类可以使用任意的访问修饰符。外部类的访问修饰符只能是public和默认。成员内部类可以直接访问外部类的方法和属性。...

常用类

内部类编译之后可生成独立的字节码文件。
内部类可以直接访问外部的属性和方法。

1。成员内部类
在类的内部定义,与实例方法和实例属性同级。
创建成员内部类,必须依赖外部对象。
创建方式:1.Outer out=new Outer();
Outer.Inner in=out.new Inner();
2.Outer.Inner in=new Outer.new Inner();
成员内部类可以使用任意的访问修饰符。
外部类的访问修饰符只能是public和默认。
成员内部类可以直接访问外部类的方法和属性。
如果成员内部类的属性和外部类的属性重名时,会优先访问内部类属性。
如果访问外部类的属性,用外部类名.this.属性
成员内部类中不能写静态属性和方法。但是可以包含静态常量(常量池中)

2.静态内部类:不依赖外部对象,直接用类名就可以访问。
级别和外部类同级别,为外部类提供功能。
创建方式:Outer.Inner in=new Outer.Inner();
访问静态内部类的静态方法:Outer.Inner.show();
特点:1.静态内部类可以使用任意访问修饰符
2.静态内部类不能直接访问外部类的实例属性和方法。但是可以直接访问外部类的静态的属性和方法。静态内部类可以有静态方法和属性。

静态的用法:静态属性、静态方法、静态内部类、静态代码块、静态导入(不太重要)。

局部内部类:定义在方法中,作用范围和创建对象仅限于当前方法中。
级别和局部变量相同。
特点:1.不能使用任何访问修饰符。
2.如果局部内部类所在方法是非静态方法,可以直接访问外部类的实例属性。如果局部内部类所在方法是静态方法,只能访问外部类的静态属性和方法,如果想访问外部类的方法和属性,可以通过创建外部对象进行访问。

//通过创建对象访问外部成员。
public static void show(){
    class Inner{
        String name="哈哈";
        public int age=12;
        public String time="昨天";
        static final int height=11;
    }
    Out out=new Out();//外部类
    System.out.println(out.name);
} 

3.局部内部类可以访问局部变量。但是局部变量必须是final,在JDK1.8 可以省略。
4.局部内部类也不能声明静态方法,可以使用静态常量。

(非静态方法)访问外部类的属性和方法:外部类名.this.属性。
匿名内部类
1.匿名内部类可以使用接口,抽象类,普通类,必须要实现接口和抽象类的方法。一般都用接口。
2.匿名内部类不能手动添加构造方法,不能包含静态的成员。名字没有,怎么构造。
3.一般不包含自己特有的方法,不能直接访问,可以通过内部对象的方法。
4.匿名内部类生成的class文件:类名$编号.class
USB usb=new USB(){}

Object

查源码就可以明白,也可以根据需要进行重写。
或者查看api
任何类,如果没有书写extends显示继承某个类,都默认直接继承Object类,或则间接继承Object
Object 可以作为参数,可以接受任何对象
Object 可以作为返回值,可以返回任何对象
getClass():返回对象的类型
instanceof差不多

System.out.println(s1.getClass());//得到class 包名.类名
System.out.println(s1.getClass().getName());//得到 包名.类名
System.out.println(s1.getClass().getSimpleName());//得到 类名
System.out.println(s1.getClass().getPackage());//得到package 包名
System.out.println(s1.getClass().getPackage().getName());//得到 包名 

hashCode():返回该对象的十进制的哈希码值。
哈希算法根据对象的地址或者字符串或者数字计算出来的int类型的数值。
哈希值并不唯一 可保证相同对象返回相同哈希码,尽量保证不同的对象返回不同的哈希码

toString() 返回该对象的字符串表示的形式。可以根据需求进行覆盖。比如:输出成员属性的值。
equals(obj) 比较两个引用是否指向同一个对象。String的equals()进行了重写。
重写的过程:
1.判断是不是和自己进行比较
2.判断obj是否为null
3.判断两个引用指向的实际对象类型是否一致
4.强制类型转换
5.依次比较各个属性值是否相同

//示例
public boolean equals(Object o) {
    if (this == o) return true;//地址是否相同
    if (o == null || getClass() != o.getClass()) return fals;是否为空和是否指向同一个实例对象
    Student student = (Student) o;
    return age == student.age &&
            Objects.equals(name, student.name) &&
            Objects.equals(card, student.card);
} 

finalize()
1.当对象被判定为垃圾对象时,由JVM自动调用此方法,用以标记垃圾对象, 进入回收队列。
2.垃圾对象:没有有效引用指向此对象时,为垃圾对象
3.垃圾回收: 由GC销毁垃圾对象,释放数据存储空间。
4.自动回收机制:JVM的内存耗尽,一次性回收所有垃圾对象。
5.手动回收机制:使用System.gc(); 通知JVM执行垃圾回收。

包装类

八个包装类,对应了八个基本数据类型。默认值为null
byte
short
int Integer
long Long
float Float
double Double
char Charact
boolean Boolean

Double Float 没有缓冲区

Charact 0 127
Byte Short Int Long Float -128 127
Boolean true false

自动装箱,在这个范围内,不会产生新的对象。
超出这个范围,会自动产生新的对象。

手动装箱:Integer a=new Integer(10);
手动拆箱:int b=Integer.intValue(a);
JDK5.0之后
自动装箱:int a=10; Integer b=a; //实际上是:Integer b=Integer.valueOf(a)
自动拆箱: Integer a=new Integer(10);int b=a;

基本类型和字符串之间转化
1.
int a=500;
String n1=n1+"";
2.
String s2=String.valueOf(a);
3.
String s3=Integer.toString(a);

字符串转成基本类型
1.

String s4="200";
int b=Integer.parseInt(s4);
int c=Integer.parseInt(s4,16);//16是指的进制 

boolean类型的字符串转成基本类型时,只要不是ture,其他字符串都是false.
boolean a=Boolean.parseBoolean(“aaa”);

String

直接字面量赋值:String name=“张三”;name=“李四”;
字符串字面值是常量创建之后不可改变。是因为存放在方法区的常量池中,改变值,是在常量池中又开辟了新的空间,旧的就变为了垃圾。所以说创建之后不可改变。name中的地址变了,直接字面量赋值,存放的常量池的地址。
使用构造方法赋值:String name=new String(“wangwu”);
栈种存放的是堆中的地址,堆中的对象又指向常量池.

String s1="abc"; String s2="xyz"; String s3=s1+s2;//这个数据是放在堆中的

s1+s2字符串时放在堆中的,没有放在常量池中。

如果在常量池中之前已经有相同的数据,不用新建常量,直接都指向该常量池的地址。

String s1="abc";//字面量赋值在常量池中
String s2="xyz";//常量池中
String s3=s1+s2;//在堆中,s3指向堆中对象,s3存放堆中地址
String s4="abc"+"xyz";//常量池中
String s5="abcxyz";//s5和s4相同,共同指向常量池中的abcxyz
System.out.println(s3==s4);
System.out.println(s4==s5);
//答案
false
true 

根据.class文件反编译如下:

Java基础语法之类和对象理解
内存分配:Java基础语法之类和对象理解

String s1="abc";
String s2="xyz";
String s3=s1+s2;
String s4=s3.intern();
String s5="abcxyz";
System.out.println(s3==s4);
System.out.println(s4==s5);

//答案
true
true 

intern() 先检查常量池, 如果常量池中已经有该字符串,直接返回地址。如果没有,会把堆中的对象的地址放在常量池中,并把地址返回给他。当后来在创建相同的字符时,因为常量池中存放了地址,直接把地址返回。
Java基础语法之类和对象理解

String s1="hello";
String s2=s1.intern();
System.out.println(s1==s2);
//答案
true 

特殊
//“java…”等一些关键的词已经在常量池中了。

System.out.println("---------特殊-------------");
String s1="ja";
String s2="va";
String s3=s1+s2;
String s4=s3.intern();
System.out.println(s3==s4);

//false 

如果String name1=“wangwu”;

String name=new String("wangwu");
String name1="wangwu";
System.out.println(name==name1);
//答案
false 

因为直接字面量赋值是存放的常量池的地址,而构造方法赋值是在堆中产生对象,再由对象指向常量池。所以地址是不同的。返回false

compareTo() 比较字符串的位置大小。前面相等,比长度。

Java基础语法之类和对象理解

可变字符串

含头不含尾

StringBuilder JDK1.5 效率高,线程不安全
StringBuffer JDK1.0 效率低,线程安全
append():追加数据
insert():插入数据
replace():替换位置
reverse():反转
delete():删除

StringBuffer str=new StringBuffer();
System.out.println("--------------append------------------");
System.out.println(str.append("abc"));
System.out.println(str.append(23));
char[] a={'a','b','c','d'};
System.out.println(str.append(a));
System.out.println(str.append(a, 0, 2));
System.out.println("--------------insert--------------------");
System.out.println(str.insert(1, "轩轩"));
System.out.println("-------------replace------------------");
System.out.println(str.replace(1, 5, "轩儿"));
System.out.println("-------------reverse------------------");
System.out.println(str.reverse());
System.out.println("-------------delete------------------");
System.out.println(str.delete(2, 5));//左闭右开
System.out.println(str.delete(0, str.length()).length()); 

本文地址:https://blog.csdn.net/m0_45196258/article/details/107655996

相关标签: java