反射
1. 通过反射获取静态属性的值或调用静态方法
- 与成员变量或调用成员方法不同,传的不是对象,而是
null
类:
public class Fu {
public static String name="张三";
public static void sayName(){
System.out.println(name);
}
}
反射:
public class Test2 {
public static void main(String[] args)
throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Class<Fu> aClass = Fu.class;
//获取所有属性对象
Field[] fields = aClass.getFields();
//获取name属性对象
Field field = aClass.getField("name");
//获取name的属性值
String value = (String)field.get(null);
//获取sayName的method对象
Method method = aClass.getMethod("sayName");
method.invoke(null);
}
}
2. 获取(修改) 私有变量或方法
- 使用 getDeclaredField( getDeclaredMethod ) 方法,私有的需通过 setAccessible(true) 使它变得可访问
- 当然也有获取所有属性和方法: getDeclaredFields() 和 getDeclaredMethods()
- 获取 class 对象: 类 -----> 类.class ; 对象 -------> 对象.getClass(); 通过Class类的方法 --------------------------->Class.forName(" 类的全路径类名 ")。
类:
@Data
public class Fu {
private String name;
public Fu(String s) {
}
private int add(int a,int b){
return a+b;
}
}
反射:
public class Test2 {
public static void main(String[] args)
throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Fu fu = new Fu("张三");
Class<? extends Fu> aClass = fu.getClass();
Field field = aClass.getDeclaredField("name");
//暴力反射
field.setAccessible(true);
String value = (String) field.get(fu);
//需传入参数的class类
Method add = aClass.getDeclaredMethod("add", int.class,int.class);
add.setAccessible(true);
//需传入参数
System.out.println(add.invoke(fu, 2, 3));
}
}
接口和抽象类
1. 接口和抽象类的区别
- 在 java 8 后接口可以定义 default 和 privat 方法 即有方法体,使得接口和类的界限变得模糊
- 但无论如何:接口不能定义成员变量
- 实现的多个接口不能有相同的 default 方法
- 如果 default 或 private 方法体里通过 this 调用其它 default 方法,不要感到疑惑,此处的 this
指向
的是 实现 这个接口的实例
。
2. 抽象类
- 抽象类可以有 成员变量 和 构造方法
- 抽象类里可以没有抽象方法
内部类
主要内容:静态内部类,成员内部类,局部内部类,匿名内部类,有的时候我们可以类比
静态变量
,成员变量
,局部
变量来理解。
如果在类 A 中定义了内部类 B ,我们可以称 A 是 B 的外部类:
1. 静态内部类 --------> 静态变量
- 如果控制访问符不是 private ,则在其他类中也可以创建它。
-
内
部类的静态
方法可以直接
访问外部类的静态变量
和方法
,但如果需要访问
外部类的成员变量
和方法
时需创建一个实例
对象再访问 -------------> 是不是很像
类的静态方法的规则。 -
外
部类的静态
方法可以通过 (类.静态变量
)或(类.静态方法
)来访问,也可以通过创建内部类的实例
来访问成员变量和方法。 - 依旧
遵循
类的静态方法只能
访问类的静态变量和静态方法,而成员
方法既能
访问类的静态变量和方法,也能
访问成员变量和方法。 - 在其他类中访问内部类: A.B prop = new A.B() -------> A.B是不是类似静态变量的写法
Bean:
@Data
public class Fu {
private static String name;
private Integer score;
public static class Zi{
private static Integer age;
private String phone;
public void sayName(){
//直接设置外部类的静态变量
name="张三";
Fu fu = new Fu();
//通过实例设置外部类的成员变量
fu.score=85;
System.out.println(name+": "+fu.score+"分");
}
}
public static void sayAge(){
//通过类名直接设置静态变量
Zi.age=25;
//创建对象设置成员变量
Zi zi = new Zi();
zi.phone="1244566222";
System.out.println(Zi.age+": "+zi.phone);
}
}
Test:
public class Test1 {
public static void main(String[] args) {
Fu.sayAge();
Fu.Zi zi = new Fu.Zi();
zi.sayName();
}
}
// 打印结果
25: 1244566222
张三: 85分
2. 成员内部类 ------> 成员变量
- 如果控制访问符不是 private ,则在其他类中也可以创建它。
-
不能
定义静态变量和方法 内
部类的成员
方法可以直接
访问外部类的静态变量
和方法
,但
需要创建实例
访问外部类的成员
变量和方法。-
外
部类的成员
方法需要通过创建内
部类的实例
来访问它的成员
变量和方法 -
外
部类的静态
方法或或其他类
访问内部类:A.B b=new A().new B() ------->A a=new A() ; (a.new) B() ---->对象.new
Bean:
@Data
public class Fu {
private static String name;
private Integer score;
public class Zi{
public void sayName(){
//直接设置外部类的静态变量
name="张三";
Fu fu = new Fu();
//通过实例设置外部类的成员变量
fu.score=85;
System.out.println(name+": "+fu.score+"分");
}
}
public static void sayAge(){
//要想访问Fu里面的成员变量,必须先new Fu()
// 再来获取Zi,即 new Fu().new Zi(),对Zi进行初始化
Zi zi = new Fu().new Zi();
zi.sayName();
}
public void say(){
//成员方法可直接访问其他成员变量,只要将Zi初始化即可:new Zi()
Zi zi = new Zi();
zi.sayName();
}
}
Test:
public class Test1 {
public static void main(String[] args) {
Fu.sayAge();
Fu.Zi zi = new Fu().new Zi();
zi.sayName();
}
}
//打印结果
张三: 85分
张三: 85分
3. 局部内部类 -------> 局部变量
- 在
方法
内部创建,没有
控制访问符,外部类无法
访问,也
不能定义静态成员。 - 和成员内部类
相似
,如果与外部类成员变量重名
,可通过outer.this.prop
(outer----->外部类,prop------>变量)访问。 - 能
直接
访问外部类所有成员-------> 即成员和静态变量方法 。 - 内部类
调用
它所在方法其他局部
变量 ,这些变量或
用final
修饰,或只
能赋值一次 。
@Data
public class Fu {
private static String name;
private Integer score;
public void say() {
class Zi {
final int a = 6;
public void sayName() {
//直接设置外部类的静态变量
name = "张三";
score = 25;
System.out.println(name + ":" + score + ":" + a);
}
}
}
}
4. 匿名内部类
- 特性与局部内部类
类似
- 假设 A 是
接口
则:A a= new A(){ } - 假设 A 是
抽象类
,且构造方法有两
个参数: A a=new A(c,d){ } - 可作为参数传入方法