提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
提示:以下是本篇文章正文内容,下面案例可供参考
一、注解
1. 内置注解
@Override : 重写 *
定义在java.lang.Override
@Deprecated:废弃 *
定义在java.lang.Deprecated
SuppressWarnings:抑制编译时的警告信息。 *
定义在java.lang.SuppressWarning
三种使用方式
1. @SuppressWarnings("unchecked") [^ 抑制单类型的警告]
2. @SuppressWarnings("unchecked","rawtypes") [^ 抑制多类型的警告]
3. @SuppressWarnings("all") [^ 抑制所有类型的警告]
2. 元注解
介绍:作用在其他注解的注解,通俗来讲就是给注解类上再填上注解
元注解:
1.@Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可
以通过反射访问。
2.@Documented - 标记这些注解是否包含在用户文档中 javadoc。
3.@Target - 标记这个注解应该是哪种 Java 成员,可以放在类的哪一个部分。
4.@Inherited - 标记这个注解是自动继承的
@Documented//注解是否包含在文档中
//用途类型:该注解可以用在类型,方法上,字段上
@Target(ElementType.FIELD)
保存策略:RUNTIME该注解保存在源码,class文件和JVM中
@Retention(RetentionPolicy.RUNTIME)
该注解可以继承
@Inherited
public @interface ColumnAnnotation {
String columnName();
String type();
String length();
}
二、Java反射机制
1.概述
JAVA反射机制是在运行状态中,获取任意一个类的结构 , 创建对象 , 得到方法,执行方法 , 属性 !;
这种在运行状态动态获取信息以及动态调用对象方法的功能被称为java语言的反射机制。
2.类加载器
java默认有三种类加载器,BootstrapClassLoader、ExtensionClassLoader、App
ClassLoader。
BootstrapClassLoader(引导启动类加载器):
嵌在JVM内核中的加载器,该加载器是用C++语言写的,主要负载加载JAVA_HOME/lib下的类库,引
导启动类加载器无法被应用程序直接使用。
ExtensionClassLoader(扩展类加载器):
ExtensionClassLoader是用JAVA编写,且它的父类加载器是Bootstrap。
是由sun.misc.Launcher$ExtClassLoader实现的,主要加载JAVA_HOME/lib/ext目录中的类
库。
它的父加载器是BootstrapClassLoader
App ClassLoader(应用类加载器):
App ClassLoader是应用程序类加载器,负责加载应用程序classpath目录下的所有jar和class文
件。它的父加载器为Ext ClassLoader
BootstrapClassLoader(引导启动类加载器)>ExtensionClassLoader(扩展类加载器)>App ClassLoader(应用类加载器)
双亲委派模型:如果一个类加载器收到了一个类加载请求,它不会自己去尝试加载这个类,而是把这个请求
转交给父类加载器去完成。每一个层次的类加载器都是如此。因此所有的类加载请求都应该传递到最顶层的
启动类加载器中,只有到父类加载器反馈自己无法完成这个加载请求(在它的搜索范围没有找到这个类)
时,子类加载器才会尝试自己去加载。委派的好处就是避免有些类被重复加载。
ClassLoader classLoader = Demo3.class.getClassLoader();//获取当前类的加载器
System.out.println(classLoader);
3.所有类的Class对象
要想了解一个类,必须先要获取到该类的字节码文件对象.
在Java中,每一个字节码文件,被夹在到内存后,都存在一个对应的Class类型的对象
通俗来说,也就是 类的类型
4.得到Class的几种方式
1. 如果在编写代码时, 指导类的名称, 且类已经存在, 可以通过
包名.类名.class 得到一个类的 类对象
2. 如果拥有类的对象, 可以通过
Class 对象.getClass() 得到一个类的 类对象
3. 如果在编写代码时, 知道类的名称 , 可以通过
Class.forName(包名+类名): 得到一个类的 类对象
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
5.反射中拿到构造器
1. 通过指定的参数类型, 获取指定的单个构造方法
getConstructor(参数类型的class对象数组)
例如:
构造方法如下: Person(String name,int age)
得到这个构造方法的代码如下:
Constructor c = p.getClass().getConstructor(String.class,int.class);
2. 获取构造方法数组
getConstructors();
3. 获取所有权限的单个构造方法
getDeclaredConstructor(参数类型的class对象数组)
4. 获取所有权限的构造方法数组
getDeclaredConstructors();
5.newInstance(Object... para)
调用这个构造方法, 把对应的对象创建出来
参数: 是一个Object类型可变参数, 传递的参数顺序 必须匹配构造方法中形式参数列表的顺
序!
6.setAccessible(boolean flag)
如果flag为true 则表示忽略访问权限检查 !(可以访问任何权限的方法)
public static void main(String[] args)throws Exception {
//通过Class.forName拿到 person2的对象
Class<Person2> p2 = (Class<Person2>) Class.forName("Person2");
//获取p2的无参构造器
Constructor<Person2> constructor = p2.getConstructor();
//创建Person2的实例对象
Person2 person2 = constructor.newInstance();
//打印输出
System.out.println(person2);
//通过Class.forName拿到 person2的对象
Class<Person2> p3 = (Class<Person2>) Class.forName("Person2");
//获取包含String name和int age的p3的有参构造器
Constructor<Person2> constructor3 = p3.getConstructor(String.class,int.class);
//创建p3的实例对象
Person2 person3 = constructor3.newInstance("张三",18);
//打印输出
System.out.println(person3);
}
6.反射拿到方法
1. getMethod(String methodName , class.. clss)
根据参数列表的类型和方法名, 得到一个方法(public修饰的)
2. getMethods();
得到一个类的所有方法 (public修饰的)
3. getDeclaredMethod(String methodName , class.. clss)
根据参数列表的类型和方法名, 得到一个方法(除继承以外所有的:包含私有, 共有, 保护, 默认)
4. getDeclaredMethods();
得到一个类的所有方法 (除继承以外所有的:包含私有, 共有, 保护, 默认)
5.invoke(Object o,Object... para) :
调用方法 ,
参数1. 要调用方法的对象
参数2. 要传递的参数列表
6.getName()
获取方法的方法名称
7.setAccessible(boolean flag)
如果flag为true 则表示忽略访问权限检查 !(可以访问任何权限的方法)
//拿到类对象
Class<Person2> person2 = (Class<Person2>) Class.forName("Person2");
//拿到类对象的无参构造器
Constructor<Person2> constructor = person2.getConstructor();
//创建对象实例
Person2 p2 = constructor.newInstance();
//通过构造器拿到方法
Method setName = person2.getMethod("setName", String.class);
//参数1:那个对象要执行setName方法
//参数2:调用时要传递的方法
Object p = setName.invoke(p2, "张三");
7.反射中拿到字段
1. getDeclaredField(String filedName)
根据属性的名称, 获取一个属性对象 (所有属性)
2. getDeclaredFields()
获取所有属性
3. getField(String filedName)
根据属性的名称, 获取一个属性对象 (public属性)
4. getFields()
获取所有属性 (public)
5. get(Object o );
参数: 要获取属性的对象
获取指定对象的此属性值
6. set(Object o , Object value)
参数1. 要设置属性值的 对象
参数2. 要设置的值
设置指定对象的属性的值
7. getName()
获取属性的名称
8. setAccessible(boolean flag)
如果flag为true 则表示忽略访问权限检查 !(可以访问任何权限的属性)
public static void main(String[] args) throws Exception{
Class p = Class.forName("Person2");
Constructor constructor = p.getConstructor();
Object o = constructor.newInstance();
Field field = p.getField("name");
//给o对象的name字段赋值为张三
field.set(o,"张三");
System.out.println(o);
}
8.注解与反射
我们可以通过反射的方式来拿到类与字段上的注解
public static void main(String[] args) throws Exception{
Class b = Class.forName("com.Book");
TableAnnotation annotation = (TableAnnotation) b.getAnnotation(TableAnnotation.class);
System.out.println(annotation.value());
Field[] fields = b.getDeclaredFields();
for (Field field : fields) {
ColumnAnnotation annotation1 = field.getAnnotation(ColumnAnnotation.class);
System.out.println(field.getName()+"属性的字段注解为"+annotation1.columnName());
}
}
总结
提示:完结