Java反射--下

获取属性:

Field getField(String name)
返回一个 Field对象反映的类或接口的 类对象表示的指定公共成员
Field[] getFields()
返回一个数组包含 Field物体反射的类或接口的 类对象代表所有可访问的公共领域
Field getDeclaredField(String name)
返回一个对象,反映了 Field指定声明字段的类或接口的 类对象表示。
Field[] getDeclaredFields()
返回 Field物体反射所有字段的类或接口的 类对象表示声明数组。

Field
方法:

Object get(Object obj)
返回的 Field表示字段的值,指定对象上。

获取方法:

方法

getMethod(String name, 类<?>… parameterTypes)
返回一个 方法对象反映的类或接口的 类对象表示的指定公共成员方法。
方法[]getMethods()
返回一个数组包含 方法物体反射所有的类或接口的 类对象表示的公共方法,包括那些由类或接口的超类和超接口继承的声明。

方法 getDeclaredMethod(String name, 类<?>… parameterTypes)
返回一个 方法对象反映指定声明方法的类或接口的 类对象表示。
方法[] getDeclaredMethods()
返回一个数组包含 方法物体反射所有声明的方法的类或接口的 类对象,代表包括公众、保护,默认(包)的访问,和私有方法,但不包括继承的方法。

Method
方法:

Object invoke(Object obj, Object… args)
调用底层的方法,这 方法对象表示,对指定对象的指定参数。
类<?>getReturnType()
返回一个 类表示这 方法对象表示法的形式返回类型。

案例一:

ArrayList list = new ArrayList()
能不能在list中添加一个字符串数据

案例二:

//pet.properties文件内容
pet=cn.ppenggs.reflect.exer.Dog
name=小白
age=5
gender=公
method=eat
package cn.ppenggs.reflect.exer;
public interface Pet {
    public void eat();
    public void play();
}
package cn.ppenggs.reflect.exer;

public class Dog implements Pet {
    private String name;
    private int age;
    private char gender;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }

    public void eat(){
        System.out.println("dog吃");
    }
    public void play(){
        System.out.println("dog玩");
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender=" + gender +
                '}';
    }
}

package cn.ppenggs.reflect.exer;

public class Cat implements Pet{
    private String name;
    private int age;
    private char gender;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }

    public void eat(){
        System.out.println("cat吃");
    }
    public void play(){
        System.out.println("cat玩");
    }

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender=" + gender +
                '}';
    }
}

package cn.ppenggs.reflect.exer;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

public class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {
        //读取properties
        Properties properties = new Properties();
        //加载文件pet.properties文件的内容到properties中
        properties.load(new FileInputStream("D:\\Day\\pet.properties"));
        //获取properties中pet key对应的值
        String value = properties.getProperty("pet");
        //根据配置文件中的全路径名称,可以创建该类的class对象
        Class clz = Class.forName(value);
        //创建对象
        Object object = clz.newInstance();
        //获取配置文件中属性的值
        String name = properties.getProperty("name");
        String age = properties.getProperty("age");
        String gender = properties.getProperty("gender");
        //1、通过反射获取属性,暴力破解 赋值
        //获取name属性
        Field fname =clz.getDeclaredField("name");
        fname.setAccessible(true);
        fname.set(object,name);
        //获取age属性
        Field fage =clz.getDeclaredField("age");
        fage.setAccessible(true);
        fage.set(object,Integer.parseInt(age));
        //获取gender属性
        Field fgender =clz.getDeclaredField("gender");
        fgender.setAccessible(true);
        fgender.set(object,gender.charAt(0));
        //调用方法method
        String method = properties.getProperty("method");
        //通过反射调用方法
        Method m = clz.getMethod(method);
        m.invoke(object);
        System.out.println(object);
    }
}
反射的优缺点
优点:

1、提高了代码的灵活性
2、提高了扩展性

缺点:

1、可以绕过泛型的检查,可能会导致集合的使用出问题
2、打破了面向对象封装

JDK1.5

静态导入:

枚举:

如果数据相对比较固定
星期一到星期日
一年的月份12个月

定义枚举类
格式:

enum 枚举名称
可以在枚举中,定义常量
常量1,常量2,常量3,常量4

注意:

1、枚举常亮只能放在首行,如果出现分号,则代表枚举常量定义结束
2、枚举常量最后可以加分号也可以不加分号
3、枚举可以保证枚举常量定义是的顺序
4、枚举本质是个类,但是该类不能通过new创建对象
5、枚举中可以定义属性,定义方法,定义构造方法(不能用public,一般使用private),但是不能放在枚举常量的前边来定义
6、枚举类不能再集成父类,可以实现接口(每个枚举常量可以分别实现接口中的方法)

package cn.ppenggs.enumx;

public class EnumDemo {
    public static void main(String[] args) {
        Week w = Week.Friday;
        Week[] weeks = Week.values();
        for (Week ws: weeks) {
            System.out.println(ws.name());
        }
    }
}
//定义枚举表示星期
enum Week{
    Sunday, Monday,Tuesday,Wednesday,Thursday,Friday,Saturday;
    public int num;
    public void method(){}
    private Week(){}

}
Swich(值) case:

int(byte char short) JDK1.7支持String
JDK1.5支持枚举
案例演示:枚举在Switch case中的应用

package cn.tedu.enumx;

public class EnumDemo3 {

    public static void main(String[] args) {
        Week1 w = Week1.星期六;
        switch (w){
            case 星期一:
                System.out.println("星期一上班");
                break;
            case 星期二:
                System.out.println("上班");
                break;
            case 星期三:
                System.out.println("上班");
                break;
            case 星期六:
                System.out.println("休息");
        }
    }
}
enum Week1{
    星期日,星期一,星期二,星期三,星期四,星期五,星期六
}
可变参数:

在方法的参数列表,可以通过定义可变参数从而实现方法的参数个数由调用者确定
格式:
数据类型…arr:可变参数
注意:
1、方法参数列表中可以定义多个可变参数吗?不可以,只能定义一个可变参数
2、方法参数列表中可以同时定义单个参数和可变参数,但是可变参数必须放到参数列表的最后
优点:
简化了代码,提高了代码的复用性
提高了代码的灵活性

public static void main(String[] args) {
         System.out.println(add(3,5));
         System.out.println(add(2,3,4));
         int[] arr = new int[]{1,2,3,4,5};
         System.out.println(add(arr));
         add();
     }
     public static int add(int... arr){
         int sum = 0;
         for(int i :arr){
             sum+=i;
         }
         return sum;
     }

JDK1.8:

接口中可以定义非抽象方法
格式:
在方法声明上加上default或是static
如果加上default,则该接口的实现类可以直接调用该方法
如果加上static,则可以通过接口.方法名直接调用
接口和抽象类的区别?
从jdk1.8开始,接口中也可以定义带有方法体的方法
Lamdba:
函数式编程:Scala

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值