栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

2021-10-26

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2021-10-26

枚举:

自己定义的Java中不存在的类型,并且取值范围比较少。

public enum Sex {

M("男"),F("女");

private final String value;
​
Sex(String value) {
    this.value = value;
}
​
public String getValue() {
    return value;
}

}
public class Test { public static void main(String[] args) { Sex sex = Sex.F; System.out.println(sex.getValue());

    Sex[] sexes = Sex.values(); //将所有枚举值取出,组成一个值的集合
    System.out.println(Arrays.toString(sexes));
    
    System.out.println(Sex.valueOf("M"));
}

注解

注解是Java1.5之后带有的一种新的类型,主要用于标记类,属性,方法,参数等。

这种标记一定会被反射这种技术所使用。

如果没有反射,注解本身是不会发生任何作用。

public @interface A { 
    public static final int i = 1; 
    public abstract int f(); 
    boolean g() default false; 
    double[] h() default {}; 
    public abstract int value() default 3; // 此处的3表示这个value方法默认的返回值 
    // 如果方法的名字是value,那么这个名字是可以不用书写的 
    // public abstract void g();  // 注解中的方法不能返回void 
    // public abstract int f(int i); // 注解中的方法不能被重载 }

    @A(f = 0) 
    public class Test { 
    
    }
元注解: 注解的注解
  1. @Target这个注解用来说明一个注解可以放在哪些内容上                                                       如果没有加这个注解,则一个注解可以随意放在哪里都可以。 @Target({ElementType.FIELD, ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
  2. @Retention表示一个注解的生命周期(源代码<字节码<运行时)                                          它的含义是一个注解可以出现在哪个阶段中。                                                                           自定义注解一般都要求是运行时阶段存在的。为什么?反射这个机制只能在运行时出现
  3. @documented用来表示这个注解应该被收录在最后的Java文档中
反射

反射: 在程序运行阶段,获取这个类中信息的能力。

获取哪些信息?属性,方法,构造器,注解。其余的暂时都获取不到。

Java中使用Class类来代表反射,所有类型都有自己的反射。获得反射一共有3种方式:

public class Test {

public static void main(@A(f = 3) String[] args) {
    class User { //局部内部类
​
    }
    
    //第1种方式
    Class c1 = User.class;
    
    try {
        //第2种方式
        Class c2 = Class.forName("com.example.A");
        //叫做通配泛型
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
​
    //第3种方式
    Class c3 = new User().getClass();
    //叫做受限泛型,表示尖括号里面必须是User或者是User的子类
}

}

使用反射操纵属性
 

public class User { private int i; public int j;

public User(int i, int j) {
    this.i = i;
    this.j = j;
}
​
@Override
public String toString() {
    return "User{" +
            "i=" + i +
            ", j=" + j +
            '}';
}

} 
public class Test { 
    public static void main(String[] args) { 
        Class c = User.class; //c表示的是User这个类的反射 //Field类表示的某个属性的反射     
        Field[] fields = c.getFields(); //getFields方法的含义是取得当这个类和所有父类中的可访问属性

        Field[] declaredFields = c.getDeclaredFields(); //getDeclaredFields获得这个类中所有的属性
​
        for (int i = 0; i < declaredFields.length; i++) {
            System.out.println(declaredFields[i]);
        }
    }

} 

属性的可能操作只有被赋值和读取其中的值,那么反射也能代替我们来做这两个操作。

属性的值要存在的前提是必须要有对象,反射也要如此。

import java.lang.reflect.Field;

public class Test { public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { Class c = User.class; //c表示的是User这个类的反射 User user1 = new User(1, 3); User user2 = new User(5, 6);

    Field fieldJ = c.getField("j"); //getField用于获得当前类或其父类中某一个可以被访问的属性
    System.out.println(fieldJ.get(user1));
    System.out.println(fieldJ.get(user2)); //get方法用于取出某个对象中这个属性的值
​
    fieldJ.set(user1, 100); //set方法用于设置某个属性的值
    fieldJ.set(user2, 200);
​
    System.out.println(user1);
    System.out.println(user2);
}

}
import java.lang.reflect.Field;

public class Test { public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { Class c = User.class; //c表示的是User这个类的反射 User user1 = new User(1, 3); User user2 = new User(5, 6);

    Field fieldI = c.getDeclaredField("i"); //getDeclaredField用于获得当前类中某一个属性
    fieldI.setAccessible(true); //将一个属性设置为可访问的setAccessible
    System.out.println(fieldI.get(user1));
    System.out.println(fieldI.get(user2)); //get方法用于取出某个对象中这个属性的值
​
    fieldI.set(user1, 100); //set方法用于设置某个属性的值
    fieldI.set(user2, 200);
​
    System.out.println(user1);
    System.out.println(user2);
}

}

使用反射操纵方法

public class User {
    public void f(){ 
        System.out.println("不带参数的,返回值为void的方法f"); 
    }

    private void f(String s){
        System.out.println("带String参数的,无返回值方法f");
    }
​
    private double f(int i, double d){
        System.out.println("带int和double参数的,返回值为double的方法f");
        return i + d;
    }

}
public class Test { 
    public static void main(String[] args) throws Exception { 
        Class c = User.class; //c表示的是User这个类的反射 
        //Method和Filed类似,用于表示某一个方法的反射 
        Method[] methods = c.getMethods();//拿到当前类和父类中所有可访问的方法 
        Method[] methods1 = c.getDeclaredMethods(); //拿到当前类所有的方法

        for (int i = 0; i < methods1.length; i++) {
            System.out.println(methods1[i]);
        }
​
    }
}

针对于方法的操作实际上只有一个,那就是调用。

public class Test { 
    public static void main(String[] args) throws Exception { 
        Class c = User.class; //c表示的是User这个类的反射 
        Method publicMethodF = c.getMethod("f"); 
        Method privateMethodF = c.getDeclaredMethod("f", int.class, double.class);     //c.getDeclaredMethod("f", String.class);

        User user = new User();
        publicMethodF.invoke(user);  //invoke专门用于反射中,调用一个方法
​
        privateMethodF.setAccessible(true);
        System.out.println(privateMethodF.invoke(user, 1, 3.14));
    }

}

使用反射操纵构造器

public class User { 
    private int id; 
    private String name; 
    public User() { 
        System.out.println("无参数构造器"); 
    }

    private User(int i, String s) {
        this.id = i;
        this.name = s;
        System.out.println("带参数构造器");
    }    
​
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + ''' +
                '}';
    }

} 
public class Test { 
    public static void main(String[] args) throws Exception { 
        Class c = User.class; //c表示的是User这个类的反射 
        Constructor constructor1 = c.getConstructor(); 
        User user1 = constructor1.newInstance(); 
        System.out.println(user1);

        Constructor constructor2 = c.getDeclaredConstructor(int.class, String.class);
        constructor2.setAccessible(true);
        User user2 = constructor2.newInstance(100, "tom");
        System.out.println(user2);
    }

}

使用反射操纵注解

public class User { 
    @Id(100)
    private int id; 
    @Name("tom") 
    private String name; 
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/351959.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号