注解
可以被其他程序读取
内置注解
(1)@Override:表示一个方法声明重写超类
(2)@Deprecated:表示它危险或者存在更好的选择
(3)@SuppressWarnings:抑制编译时的警告信息,需要参数
SuppressWarnings(“all”);
SuppressWarnings(“unchecked”);
SuppressWarnings(“unchecked”,“deprecation”);
等等
元注解
负责注解其他注解
java.lang.annotation包中
@Target:描述注解的使用范围
- ElementType.TYPE 类名
- ElementType.FIELD 字段
- ElementType.METHOD 方法
- 等等
@Retention:描述注解的生命周期
- SOURCE<CLASS<RUNTIME
@Documented:说明该注解将被包含在javadoc中
@Inherited:说明子类可以继承父类中的该注解
@Target(value = {ElementType.METHOD}) //将注解放在方法上
@Retention(value = RetentionPolicy.RUNTIME) //表示注解在运行时有效
@Documented //表示注解将生成在javadoc中
@Inherited //子类可以继承父类注解
public @interface Myannotation{
}
自定义注解
//元注解
public @interface 注解名{
//注解参数
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//自定义注解
public class Test02 {
//注解可以显示赋值
@MyAnnotation2(name = "A")
public void test(){
}
@Myannotation3("") //参数是value且只有一个,那么可以省略value
public void test2(){
}
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2{
//注解的参数:参数类型 参数名()
String name() default ""; //默认为空
int age() default 0;
int id() default -1; //默认值为-1代表不存在
int[] array() default {1,2,1};
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface Myannotation3{
String value();
}
反射
动态语言:可以在运行的时候改变自身结构
(1)反射是java被视为动态语言的关键,反射机制允许程序在执行期间借助Reflection API取得任何类的内部信息,并直接操作任意对象的内部属性及方法
Class c=Class.forName("java.lang.String")
(2)加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以,我们称为反射
正常方式:引入需要的“包类名称–>通过new实例化–>取得实例对象
方式方式:实例化对象–>getClass()方法–>得到完整的"包类"名称
Class类
在Object类中定义了以下方法,此方法将被所有子类继承
public final Class getClass()
(1)Class本身也是一个类
(2)Class对象只能由系统创建
(3)一个加载的类在JVM中只会有一个Class实例
(4)一个Class对象对应的是一个加载到JVM的一个.class文件
(5)每个类的实例都会记得自己是由哪个Class实例所生成
(6)通过Class可以完整地得到一个类中的所有被加载的结构
(7)Class类是Reflection的根源,针对任何你想动态加载、运行的类,要先获得Class对象
方法名 | 功能说明 |
---|---|
static ClassforName(String name) | 返回指定类名name的Class对象 |
Object newInstance() 已废弃 | 调用无参构造方法,返回Class对象的一个实例 |
getName() | 返回此Class对象锁表示的实体的名称 |
Class getSuperClass() | 返回当前Class对象的父类的Class对象 |
Class[] getinterfaces() | 获取当前Class对象的接口 |
ClassLoader getClassLoader() | 返回该类的类加载器 |
Constructor[] getConstructors() | 返回一个包含某些Constructor对象的数组 |
Method getMothed(String name,Class…T) | 返回一个Method对象,此对象的形参类型为paramType |
Field[] getDeclareFields() | 返回Field对象的一个数组 |
-
获取class实例
-
通过已知类获取
Class c2=Person.class;
-
通过已知类的实例对象的getClass()方法获取
Class c1 = person.getClass();
-
通过Class类的静态方法forName()获取
Class c3=Class.forName("reflection.Person");
-
基本内置类型的包装类都有type属性
Class c4=Integer.TYPE;
-
-
哪些类可以有class对象
(1)class:外部类,成员内部类,静态内部类,局部内部类,匿名内部类
(2)interface
(3)数组
(4)enum
(5)annotation:注解@interface
(6)primitive type:基本数据类型
(7)void
import java.lang.annotation.ElementType;
//所有类型的class
public class test03 {
public static void main(String[] args) {
Class c1=Object.class; //类
Class c2=Comparable.class; //接口
Class c3=int[].class; //一维数组
Class c4=Override.class; //注解
Class c5= ElementType.class; //枚举
Class c6=int[][].class; //二维数组
Class c7=Integer.class; //基本数据类型
Class c8=void.class; //void
Class c9=Class.class; //Class
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(c4);
System.out.println(c5);
System.out.println(c6);
System.out.println(c7);
System.out.println(c8);
System.out.println(c9);
//一个类(型)只有一个class对象
int[] a=new int[10];
int[] b=new int[100];
System.out.println(a.getClass().hashCode());
System.out.println(b.getClass().hashCode());
test03 t1=new test03();
test03 t2=new test03();
System.out.println(t1.getClass().hashCode());
System.out.println(t2.getClass().hashCode());
}
}
类加载内存分析
类初始化
类加载器
public class test06 {
public static void main(String[] args) throws ClassNotFoundException {
//获取系统类加载器
ClassLoader systemClassLoader=ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);
//获取系统类加载器的父类加载器-->扩展类加载器
ClassLoader parent=systemClassLoader.getParent();
System.out.println(parent);
//获取扩展类加载器的父类加载器-->根加载器 java无法直接获取
ClassLoader grandparent=parent.getParent();
System.out.println(grandparent);
//测试当前类是哪个加载器加载的
ClassLoader classLoader = Class.forName("reflection.test06").getClassLoader();
System.out.println(classLoader);
//测试jdk内置的类是哪个加载器加载的
classLoader = Class.forName("java.lang.Object").getClassLoader();
System.out.println(classLoader);
//如何获得系统类加载器可以加载的路径
System.out.println(System.getProperty("java.class.path"));
}
}
创建运行时类的对象
获取运行时类的完整结构
通过反射获取运行时类的完整结构
Field、Method、Constructor、Superclass、Interface、Annotation
class User{
private String name;
private int id;
private int age;
public User(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
public User(){}
@Override
public String toString() {
return ("name="+this.name+",id="+this.id+",age="+this.age);
}
public String getName() {
return name;
}
public void setName(String name) {
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;
}
}
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
//获得类的信息
public class test07 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
//(1)
Class c1 = Class.forName("reflection.User");
//获得类的名字 包名.类名
System.out.println(c1.getName());
//获得类的simple名字 类名
System.out.println(c1.getSimpleName());
//(2)
User user = new User();
c1 = user.getClass();
//获得类的名字 包名.类名
System.out.println(c1.getName());
//获得类的simple名字 类名
System.out.println(c1.getSimpleName());
System.out.println("------------------------------");
//获得类的属性
Field[] fields = c1.getFields(); //只能找到public属性
for (Field field : fields) {
System.out.println(field);
}
System.out.println("------------------------------");
fields=c1.getDeclaredFields(); //可以找到所有的属性
for (Field field : fields) {
System.out.println(field);
}
System.out.println("------------------------------");
//获得指定属性
// Field name=c1.getField("name"); //保错,因为name不是public
Field name=c1.getDeclaredField("name");
System.out.println(name);
System.out.println("------------------------------");
//获得类的方法
Method[] methods = c1.getMethods(); //获得本类及父类的所有public方法
for (Method method:methods){
System.out.println(method);
}
System.out.println("");
methods = c1.getDeclaredMethods(); //获得本类的全部方法
for (Method method:methods){
System.out.println(method);
}
System.out.println("------------------------------");
//获得指定方法
//因为java有重载
Method getName = c1.getMethod("getName",null); //方法名 参数
System.out.println(getName);
Method setName = c1.getMethod("setName", String.class); //方法名 参数类型.class
System.out.println(setName);
System.out.println("------------------------------");
//获得指定构造器
Constructor[] constructors = c1.getConstructors();
for (Constructor constructor:constructors){
System.out.println(constructor);
}
System.out.println("");
constructors = c1.getDeclaredConstructors();
for (Constructor constructor:constructors){
System.out.println(constructor);
}
//获得指定构造器
System.out.println(c1.getDeclaredConstructor(String.class, int.class, int.class));
}
}
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
//通过反射动态创建对象
public class test08 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException, NoSuchFieldException {
//1.获得class对象
Class c1=Class.forName("reflection.User");
Constructor[] constructors = c1.getConstructors();
//2.通过class对象创建对象
User user1 =(User) c1.newInstance(); //调用无参构造
System.out.println(user1);
System.out.println("---------------------------------------");
//由构造器创建对象
User user2 =(User) c1.getDeclaredConstructor(String.class,int.class,int.class).newInstance("A",18,18);
System.out.println(user2);
//3.通过反射调用普通方法
User user3 =(User) c1.getDeclaredConstructor().newInstance();
//(1)获取方法
Method setAge = c1.getDeclaredMethod("setAge", int.class);
//invoke(对象名,参数);
setAge.invoke(user3,1);
System.out.println(user3.getAge());
// user3.setName("1");
// System.out.println(user3.getName());
//4.通过反射操作对象
User user4 =(User) c1.getDeclaredConstructor().newInstance();
Field name = c1.getDeclaredField("name");
//取消私有属性的检查属性 关闭属性的安全监测 比反射直接调用快了几倍
name.setAccessible(true);
name.set(user4,"AA");
System.out.println(user4.getName());
// System.out.println(name.getName());
}
}
反射操作泛型
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 test09 {
public void test01(Map<String,User> map, List<User> list){
}
public Map<String,User> test02(){
System.out.println("test02");
return null;
}
public static void main(String[] args) throws NoSuchMethodException {
//通过注解获取泛型
Method method = test09.class.getMethod("test01", Map.class, List.class);
//get Generic Parameter Types 获得泛型参数类型
Type[] genericParameterTypes = method.getGenericParameterTypes();
for (Type genericParameterType : genericParameterTypes) {
//打印泛型参数类型
System.out.println("#"+genericParameterType);
//判断泛型参数类型是否等于结构化参数类型
if (genericParameterType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
Method method1 = test09.class.getMethod("test02");
Type genericReturnType = method1.getGenericReturnType();
if (genericReturnType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println("2 "+actualTypeArgument);
}
}
}
}
反射操作注解
getAnnotation
getAnnotations
ORM:Object relationship Mapping 对象关系映射
import java.lang.annotation.*;
import java.lang.reflect.Field;
//反射操作注解
public class test10 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class c1 = Class.forName("reflection.B");
//通过反射获得注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
//获得注解value的值
Table table =(Table) c1.getAnnotation(Table.class);
System.out.println(table.value());
//获得类指定的注解
Field name = c1.getDeclaredField("name");
Field_ annotation = name.getAnnotation(Field_.class);
System.out.println(annotation.columnName());
System.out.println(annotation.type());
System.out.println(annotation.length());
}
}
@Table("db_B")
class B{
@Field_(columnName = "id",type = "int",length = 10)
private int id;
@Field_(columnName = "age",type = "int",length = 10)
private int age;
@Field_(columnName = "name",type = "varchar",length = 20)
private String name;
public B(int id, int age, String name) {
this.id = id;
this.age = age;
this.name = name;
}
public B() {
}
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 Field_{
String columnName();
String type();
int length();
}