反射与内部类

反射

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){ }
  • 可作为参数传入方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值