package definition;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public class DefAnno {
//注解参数无默认值,需赋值。注解中有多个参数名时,参数名不能省略。
@MyAnnotation(nameArray = {
"Lily","Tom"})
public void test(){
}
//注解中只有一个参数时,可以省略value参数名
@MyAnnotation1("Mary")
public void test1(){
}
}
//自定义注解
@Target({
ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
String name() default "";
int age() default 0;
String[] nameArray();
}
//自定义注解,只有一个参数
@Target({
ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation1{
String value();
}
Reflection(反射)是Java被视为动态语言(在运行时,可以根据某些条件改变自身结构)的关键。反射机制允许程序在执行期间借助Reflection API获取任何类的内部信息,并能直接操作任何内部属性及方法。
反射方式:实例化对象---->getClass()---->得到完整的“包类”名称。
Reflection功能:
Reflection优缺点
Class c = Class.forName("com.school.reflection.User")--获取User类对应的Class类
Class类的常用方法
获取Class类的方式:
已知具体的类:Person.Class
已知某个类的实例:person.getClass();
已知一个类的路径:Class.forName(“类路径”)
基本内置类型的包装类都有一个Type属性
Class c1 = Integer.TYPE;
class、interface、数组、enum、annotation、primitive type(基本数据类型)和void
package definition;
public class Reflection {
//主动调用:main方法对应的类被初始化
public static void main(String[] args) throws ClassNotFoundException {
System.out.println("main类被初始化");
//主动调用:new类的实例
Son son = new Son();
//主动调用:反射
Class c = Class.forName("definition.Son");
//被动调用:子类调用父类静态变量
System.out.println(Son.b);
//通过数组定义类引用,不会触发此类的初始化
Son[] sonArray = new Son[10];
//引用常量不会触发此类的初始化
System.out.println(Son.M);
}
}
class Father{
static int b = 10;
static{
System.out.println("父类被初始化");
}
}
class Son extends Father{
static {
System.out.println("子类被初始化");
}
static final int M = 10;
}
类加载器:将类的class文件读入内存,将静态数据转换为方法区运行时的数据结构并创建一个java.lang.Class对象,此过程有类加载器完成。
加载器类型:引导类加载器:负责java平台核心库。扩展类加载器;负责jre/lib/ext目录下的jar包或D java.ext.dirs指定目录下的jar包装入工作库。系统类加载器:负责java-classpath或D java.class.path目录下的类或jar包装入工作库。
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); --获取系统类的加载器
ClassLoader parent = systemClassLoader.getParent(); --获取扩展类加载器
ClassLoader parent1 = parent.getParent(); --获取引导类加载器
Class.forName("类路径名"); --当前类由哪个类加载器加载
System.getProperty("java.class.path") --获取系统记载器可以加载的路径
双亲委派机制:如自定义类String,在类加载过程中,在系统/扩展/引导加载器中寻找String类,由于存在java.lang.String类,自定义类会失效,保证安全性。
Class c = Class.forName("类路径名");
c1.getFields(); --只能获取public的属性
c1.getDeclaredField(); --获取类中全部属性
c1.getDeclaredField("name"); --获取指定属性
c1.getMethods() --获取本类以及父类的public方法
c1.getDeclaredMethods(); --获取本类中的所有方法
c1.getMethods(方法名,方法所需参数)
c1.getConstructors(); --获得public构造器方法
c1.getDeclaredConstructors(); --获得所有构造器方法
c1.getDeclaredConstructors(参数:String.class,int.class); ----获得指定构造器方法
创建类的对象:
调用指定方法:
setAcessible()
User类:
package reflector;
public class User {
private String name;
private int age;
private String sex;
public User(){
}
public User(String name,int age,String sex){
this.name = name;
this.age = age;
this.sex = sex;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
private void display(String name,int age,String sex){
System.out.println("姓名:" + name + "," + "年龄:" + age + "," + "性别:" + sex);
}
public void test(){
System.out.println("dsddd");
}
}
反射创建类实例,调用类方法以及调用类字段:
package reflector;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class RefleExec {
public static void main(String[] args) throws Exception {
//创建class对象
Class c = Class.forName("reflector.User");
//方法一:构造User对象
User user = (User)c.newInstance();
//方法二:构造User对象
Constructor constructor = c.getDeclaredConstructor(String.class,int.class,String.class);
User user1 = (User)constructor.newInstance("sgay",14,"男");
// System.out.println(user+" "+user1);
//反射调用方法
Method method = c.getDeclaredMethod("display",String.class,int.class,String.class);
//如果是私有方法,修改访问权限
method.setAccessible(true);
method.invoke(user,"dfdd",20,"男");
// user.test();
// System.out.println( user1.getName());
//反射操作属性
Field field = c.getDeclaredField("name");
field.setAccessible(true);
field.set(user,"dcss");
// user.setName("ysadc");
System.out.println(user.getName());
}
}
parameterizedType:表示一种参数化类型,如:collection
GenericArrayType:表示一种参数化类型或者类型变量的数组类型
TypeVariable:各种类型变量的公共父接口
WildcardType:表示一种通配符类型表达式
package reflector;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
public class Generic {
public void test1(Map<String,User> map, List<User> list){
System.out.println("test1");
}
public Map<String,User>test2(){
System.out.println("test2");
return null;
}
public static void main(String[] args) throws NoSuchMethodException {
Method method = Generic.class.getDeclaredMethod("test1", Map.class, List.class);
//获取方法中的泛型参数
Type[] genericParameterTypes = method.getGenericParameterTypes();
for (Type genericParameterType:genericParameterTypes ){
// System.out.println(genericParameterType);
//Map --得到String,User
if(genericParameterType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
for(Type actualTypeArgument:actualTypeArguments){
System.out.println(actualTypeArgument);
}
}
}
//获取方法的返回值反泛型类型
Method method1 = Generic.class.getDeclaredMethod("test2");
Type returnType = method1.getGenericReturnType();
if(returnType instanceof ParameterizedType){
Type[] actualTypeArguments= ((ParameterizedType) returnType).getActualTypeArguments();
for(Type actualTypeArgument:actualTypeArguments){
System.out.println(actualTypeArgument);
}
}
}
}
package reflector;
import java.lang.annotation.*;
import java.lang.reflect.Field;
public class RefOperAnno {
public static void main(String[] args) throws NoSuchFieldException {
//获取类的注解
Class c = Student.class;
Annotation[] annotations = c.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
//获取注解的值
Table table = (Table)c.getAnnotation(Table.class);
System.out.println(table.value());
//获取属性注解
Field field = c.getDeclaredField("id");
FieldPro fieldPro = (FieldPro)field.getAnnotation(FieldPro.class);
System.out.println(fieldPro.columnName());
System.out.println(fieldPro.length());
System.out.println(fieldPro.type());
}
}
@Table("db_student")
class Student{
@FieldPro(columnName = "id",type = "int",length = 100)
private int id;
@FieldPro(columnName = "age",type = "int",length = 100)
private int age;
@FieldPro(columnName = "name",type = "String",length = 100)
private String name;
public Student(int id,int age,String name){
this.id = id;
this.age = age;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//类注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Table{
String value();
}
//属性注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldPro{
String columnName();
String type();
int length();
}