c语言/c++转Java学习笔记---进阶问题
- 1.字段变量与局部变量
- 2.虚方法
- 3.构造方法
- 4.初始化
- 5.构造方法的执行过程
- 6.对象清除与垃圾回收
- 7.内部类和匿名类
- 8.Lambda表达式
- 9.装箱、枚举、注解
- 10.引用与指针
- 11.相等还是不等
1.字段变量与局部变量
- 前者是在类中,后者是在方法中定义的变量或方法的参变量
- 存储位置,字段变量为对象的一部分、存在于堆中,局部变量是存在于栈中的,局部变量是存在于栈中的。
- 初始值:字段变量可以自动赋值,局部变量须显式赋值
- 字段变量属于类,可以用public,private,static,final修饰
- 局部变量不能被访问控制符及static修饰
- 格式:变量 instanceof 类型(结果是Boolean值)
2.虚方法
- java中普通的方法是虚方法
- 但static,private方法不是虚方法调用
- static,private与虚方法编译后的指令是不同的
- static的方法,以声明类型为准,与实例类型无关
- private方法子类看不见,也不会被虚化
- final方法子类不能覆盖,不存在虚化问题`
3.构造方法
- 对象都有构造方法
- 如果没有,编译器加一个default构造方法
- 调用本类或父类的构造方法
this调用本类的构造方法
super调用直接父类的构造方法
this或super要放在第一条语句,且只能够有一条 - 如果没有this及super,则编译器自动加上super(),即调用直接父类不带参数的构造方法
- 因此必须令所有父类的构造方法都得到调用,否则整个对象的构建就可能不正确
4.初始化
1.创建对象时初始化,如
Person p = new Person(){{age=18;name="李明"}};
- 这样可以针对没有构造函数,但又要赋值
- 注意两个大括号
2.实例初始化
- 在类中直接写
{语句} - 实例初始化,先于构造方法{}中的语句执行
3.静态初始化
- static{语句}
- 静态初始化,在第一次使用这个类的时候执行
- 先于实例初始化执行
5.构造方法的执行过程
- 就单个的类来讲,执行顺序是 静态初始化块 -> 初始化块 -> 构造器
- 构造方法执行过程遵循以下步骤
1.调用本类或父类的构造方法,直至最高一层(Object)
2.按照声明顺序执行字段的的初始化
3.执行构造函数中的各语句
总结:先父类构造,再本类成员赋值,最后执行构造方法中的语句
6.对象清除与垃圾回收
1.垃圾回收是由java虚拟机的垃圾回收线程来完成的,任何对象都有一个引用计数器,当其值为0时,说明该对象可回收
2.System.gc()方法
system类的static方法,可以要求系统进行垃圾回收
3.java中没有“析构方法”,但Object的finalize()有类似功能
- 系统在回收时会自动调用对象的finalize()方法。
protected void finalize() throws Throwable{} - 子类的finalize()方法
可以在子类的finalize()方法释放系统资源
一般来说子类的finalize()方法应该调用到父类的finalize()方法,以保证父类的清理工作能够正常进行
4.try-with-resources
- 对于实现了java.lang.AutoCloseable的对象
try(Scanner scanner= new Scanner(…)){…}
会自动调用close()方法,相当于finally{Scanner.close()};
7.内部类和匿名类
- 内部类是在其他类中的类
- 匿名类是一种特殊的内部类,它没有类名
1.内部类
- 内部类不能与外部类同名
- 内部类中可以直接访问外部类的字段及方法
- 如果内部类中有与外部类同名的字段或方法则可以用,外部类.this.字段及方法
- 内部类与类中的字段、方
- 法一样都是外部类的成员,它的前面也可以有访问控制符和其他修饰符
- 用static修饰内部类 表面该内部类实际是一种外部类
2.局部类
- 在一个方法中也可以定义类,这种类称为“方法中的内部类”,或者叫局部类
3.匿名类
- 匿名类是一种特殊的内部类,它没有类名,在定义类的同时就生成该对象的一个实例(一次性使用的类)
- 不取名字,直接用其父类或接口的名字
- 类的定义的同时就创建实例,即类的定义的前门有一个new
- 在构造对象的时候使用父类构造方法
- 应用:1.注册事件监听器 2.作为方法的参数(排序时比较大小接口)
8.Lambda表达式
1.基本写法:(参数)->结果
- 大体上相当于其他语言的“匿名函数”或“函数指针”
- 在线程的例子中
new Thread (()->{...}).start
- 在积分的例子中`d=Integral(x->Math.sin(x),0,1,EPS);
- 在按钮处理事件中 btn.addActionListener(e->{…});
2.能写成Lambda的接口的条件
- 由于Lambda只能表示一个函数,所以能写成Lambda的接口要求包含且最多只能有一个抽象函数
- 这样接口可以用@FunctionalInterface来表示。称为函数式接口
- 如
@FunctionalInterface
interface Fun{double fun(double x);}
9.装箱、枚举、注解
1.基本类型的包装类将基本类型包装成Object(引用类型)
例如
package com.demo;
// 以int数据为例实现一个包装处理的定义
class Int {
private int data ; //包装了一个基本数据类型
public Int(int data) {
this.data = data ;
}
public int intValue() {
return this.data ;
}
}
public class BaoZhuang {
public static void main(String[] args) {
//装箱——将基本数据类型保存在包装类之中
//Int temp = new Int(10) ;
Object obj = new Int(10) ;
//拆箱——从包装类对象中能够获取基本数据类型
//int x = temp.intValue() ;
int x = ((Int)obj).intValue() ;
System.out.println(x * 2) ;
}
}
2.枚举
- 枚举(enum)是一种特殊的class类型
如
enum Light{Red,Yellow,Green};
Light light=Light.Red
也可以在enum定义体中,添加字段、方法构造方法
3.注解
- 注解又称为注记、标记、标注、注释,是在各种语法要素上附加信息,以供编译器或其他程序使用
- 所有的注解都是java.lang.annotation.Annotation的子类
- 常用的注解如
@Override 表示覆盖父类的方法
@Deprecated 表示过时的方法
@SupppressWarnings 表示让编译器不产生警告
10.引用与指针
- Java中没有指针,引用的实质就是指针,但他是受控的、安全的
- C语言指针在java中的体现
(1)传地址->对象
(2)指针运算->数组
(3)函数指针->接口Lambda表达式
(4)指向节点的指针->对象的引用
(5)使用JNI
Java Native Interface(JNI)
它允许Java代码和其他语言写的代码进行交互
11.相等还是不等
1.数值类型:转换后比较
2.浮点数:判断两个数的相差是不是很小
3.boolen类型无法与int比较
Integer i= new Integer(10);
Integer j= new Integer(10);
System.out.println(i==j);//false因为对象是两个
Integer i= 10;
Integer j= 10;
System.out.println(i==j);//应为对象有缓存(-128到127有)
Integer i= 200;
Integer j= 200;
System.out.println(i==j);//false因为对象是两个
4.枚举类型:内部进行了唯一实例化,所以可以判断
5.引用对象:
是直接看两个引用是否一样
如果要判断内容是否一样,则要重写equals方法
如果重写equals方法,则最好重写hashCode()方法
6.String对象
判断相等,一定不要用==,要用equals
但是字符串常量及字符串常量会进行内部化(interned)相同的字符串常量是 相等 的
String hello="Hello",lo="lo";
System.out.println(hello=="Hello");//true
System.out.println(Other.hello=="Hello");//true
System.out.println(hello=="Hel"+"lo");//true
System.out.println(hello=="Hel"+lo);//false
System.out.println(hello==new String("Hello"));//false
System.out.println(hello==("Hel"+lo).intern);//true