注解与反射(注解与反射restaurant类)

  本篇文章为你整理了注解与反射(注解与反射restaurant类)的详细内容,包含有注解与反射是怎么让java变成准动态语言的 注解与反射restaurant类 注解反射原理 注解反射修改注解属性 注解与反射,希望能帮助你了解 注解与反射。

  1.内置注解

  (1)@Override重写注解

  加上此注解必须重写父类的方法

  (2)@SuppressWarnings("all")的作用

  
 

  除了上图可以放在方法名上,此外它还可以放到类名上用于镇压所有的警告

  (3)@Deprecated注解

  虽然是已经过时的,但是任然可以运行使用

  2.元注解

  (1)@Target注解

  target源码如下

  
 

  ElementType源码如下

  target表示该注解可以应用于哪些地方,比如下图value里只写了方法类型,该注解就只能用在方法名上,放在类名上就会报错,而当在value里添加了类的类型之后,该注解就可以应该用于类名上

  (2)@Retention注解

  Retention表示我们的注解在什么地方还有效

  runtime class sources;若其value中定义的是runtime,则在class和sources中也可以使用;若在value中定义的是class,则在sources中可以使用在runtime中就不可以使用

  (3)@Documented注解

  @Documented:表示是否将我们的注解生成在Javadoc中
 

  (4)@Inherited注解

  @Inherited:子类可以继承父类的注解
 

  3.自定义注解

  详情见代码解释

  点击查看代码

  

package com.Tang.annotation;

 

  import java.lang.annotation.ElementType;

  import java.lang.annotation.Retention;

  import java.lang.annotation.RetentionPolicy;

  import java.lang.annotation.Target;

  public class TestAnnotation {

   //注解可以显示赋值,如果参数后面没有默认值,就必须要给注解参数赋值,如果有默认值则可以不给参数赋值

   @MyAnnotation2(name = "Twq",age = 2,schools = {"国科大","沈计所"})

   public void test(){}

   //如果注解中只有一个参数,且参数名为value,则在为其赋值的时候value可以省略直接赋值,否则必须为其赋值时必须写参数名

   @MyAnnotation3("唐wq")

   public void test1(){}

  //自定义注解

  @Target({ElementType.METHOD,ElementType.TYPE})//这两行为自定义注解的固定写法

  @Retention(RetentionPolicy.RUNTIME)

  @interface MyAnnotation2{

   //自定义注解的格式:参数类型 参数名 + ();

   String name() default "";

   int age() default 0;

   int id() default -1;//如果默认值为-1,代表不存在

   String[] schools() default {"中科院"};

  @Target({ElementType.METHOD,ElementType.TYPE})//这两行为自定义注解的固定写法

  @Retention(RetentionPolicy.RUNTIME)

  @interface MyAnnotation3{

   String value();

  

 

  1.反射的概念

  2.反射的作用

  使用反射前与使用反射都能做的事的对比

  点击查看代码

  

package com.Tang.reflect;

 

  import org.junit.Test;

  import java.lang.reflect.Constructor;

  import java.lang.reflect.Field;

  import java.lang.reflect.Method;

  public class BeforeAfter {

   //学习反射之前能对Person1类能做的事

   @Test

   public void test(){

   //1.创建Person类的对象,并调用有参构造

   Person1 p1 = new Person1("Tom",12);

   //2.通过对象,调用public属性

   //调用属性

   p1.age = 10;

   System.out.println(p1.toString());

   //3.通过对象调用public方法

   p1.show();

   //在Person类的外部,不可以通过Person类的对象调用其内部私有结构

   //比如:name属性、showNation()方法以及私有的构造器

   //学习反射之后

   @Test

   public void test1() throws Exception {

   /*程序经过编译(运行javac命令)之后,会生成一个或多个字节码文件(.class结尾)

   然后使用java.exe对某个字节码文件进行解释运行,相当于将某个字节码文件加载到内存中

   ,加载到内存中的类,我们成为运行时类,此运行时类就作为Class的一个实例*/

   Class clazz = Person1.class;//形式上看Person1是Class的对象

   //1.通过反射创建Person1类的对象,类似于调用Person1的有参构造,

   //传入一个子符串类型的姓名,与一个int类型的年龄

   Constructor cons = clazz.getConstructor(String.class, int.class);

   /*newInstance()调用此方法,创建对应的运行时类的对象,内部调用了运行时类的空参的构造器

   要想此方法正常的创建运行时类的对象,要求:(1)运行时类必须提供空参的构造器,(2)空参的构造器的访问权限得够,通常设置为public

   在Javabean中要求提供一个public的空参构造器,原因:便于通过反射,创建运行时类的对象;便于子类继承此运行时类,默认调用super()时保证父类有此构造器*/

   Object obj = cons.newInstance("Tom", 12);

   Person1 p1 = (Person1) obj;

   System.out.println(obj .toString());

   //2.通过反射,调用对象指定的属性

   Field age = clazz.getDeclaredField("age"); //调用属性,传入调用属性的名字

   age.set(p1,10);//给p1对象的age属性赋值

   System.out.println(p1.toString());

   //3.通过反射,调用对象指定的方法

   Method show = clazz.getDeclaredMethod("show");//传入要调方法的名字

   show.invoke(p1);

   System.out.println("********************");

   //4.通过反射,可以调用Person类的私有结构,比如:私有的构造器,方法、属性

   //1)调用私有的构造器

   Constructor cons1 = clazz.getDeclaredConstructor(String.class);

   cons1.setAccessible(true);

   Object obj1 = cons1.newInstance("Twq");

   System.out.println(obj1.toString());

   //2)调用私有的方法

   Method showNation = clazz.getDeclaredMethod("showNation", String.class);

   showNation.setAccessible(true);

   showNation.invoke(p1,"中国");

   //3)调用私有的属性

   Field name = clazz.getDeclaredField("name");

   name.setAccessible(true);

   name.set(p1,"jerry");

   System.out.println(p1.toString());

  class Person1{

   private String name;

   public int age;

   public Person1() {

   public Person1(String name, int age) {

   this.name = name;

   this.age = age;

   private Person1(String name) {

   this.name = name;

   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;

   @Override

   public String toString() {

   return "Person1{" +

   "name=" + name + \ +

   ", age=" + age +

   };

   public void show(){

   System.out.println("你好,我是一个人");

   private String showNation(String nation){

   System.out.println("我的国籍是:"+nation);

   return nation;

  

 

  运行结果图

  3.获取Class对象的基本用法

  点击查看代码

  

package com.Tang.reflect;

 

  public class Test01 {

   public static void main(String[] args) throws ClassNotFoundException {

   //通过反射获取类的class对象

   Class c1 = Class.forName("com.Tang.reflect.User");

   System.out.println(c1);

   Class c2 = Class.forName("com.Tang.reflect.User");

   Class c3 = Class.forName("com.Tang.reflect.User");

   Class c4 = Class.forName("com.Tang.reflect.User");

   //一个类在内存中只有一个Class对象

   //一个类被加载后,类的整个结构都会被封装在Class对象中

   System.out.println(c2.hashCode());

   System.out.println(c3.hashCode());

   System.out.println(c4.hashCode());

  class User{

   private String name;

   private int id;

   private int age;

   public User() {

   public User(String name, int id, int age) {

   this.name = name;

   this.id = id;

   this.age = 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;

   @Override

   public String toString() {

   return "User{" +

   "name=" + name + \ +

   ", id=" + id +

   ", age=" + age +

   };

  

 

  运行结果图

  4.获取Class类的对象几种方式

  点击查看代码

  

package com.Tang.reflect;

 

  public class Test02 {

   public static void main(String[] args) throws ClassNotFoundException {

   Person person = new Student();

   System.out.println("这个人是:"+person.name);

   //重点掌握前三种方法

   //方式一:通过对象获得Class对象

   Class c1 = person.getClass();

   System.out.println(c1.hashCode());

   //方式二:forname获得

   Class c2 = Class.forName("com.Tang.reflect.Student");

   System.out.println(c2.hashCode());

   //方式三:通过类名.class获得

   Class Student c3 = Student.class;

   System.out.println(c3.hashCode());

   //方式四:实用类的加载器:Classloader

   ClassLoader classLoader = Test02.classgetClassLoader();

   Class c4 = classLoader.loadClass("com.Tang.reflect.Student");

   System.out.println(c4.hashCode());

   //基本内置类型的包装类都有一个Type属性

   Class c5 = Integer.TYPE;

   System.out.println(c4);

   System.out.println(c4.hashCode());

   //获得父类类型

   Class c6 = c1.getSuperclass();

   System.out.println(c5);

  class Person{

   public String name;

   public Person() {

   public Person(String name) {

   this.name = name;

   @Override

   public String toString() {

   return "Person{" +

   "name=" + name + \ +

   };

  class Student extends Person{

   public Student(){

   this.name = "学生";

  class Teacher extends Person{

   public Teacher(){

   this.name = "老师";

  

 

  运行结果图

  5.所有类型的Class对象

  点击查看代码

  

package com.Tang.reflect;

 

  import java.lang.annotation.ElementType;

  public class Demo {

   public static void main(String[] args) {

   //Class实例可以是哪些结构的说明:

   Class c1 = Object.class; //类

   Class c2 = Comparable.class; //接口

   Class c3 = String[].class; //一维数组

   Class c4 = int[][].class; //二维数组

   Class c5 = Override.class; //注解

   Class c6 = ElementType.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);

   System.out.println("============");

   //只要数组元素类型与维度一样,就是同一个Class

   int[] a = new int[10];

   int[] b = new int[100];

   System.out.println(a.getClass().hashCode());

   System.out.println(b.getClass().hashCode());

  

 

  运行结果图

  6.类的加载(非重点)

  7.通过反射创建运行时类的对象(重点)

  点击查看代码

  

//在后期使用框架,后台不确定要造哪个对象,此时就不能通过new加构造器的方式去写,必须通过反射的方式去写

 

   @Test

   public void test2(){

   for (int i = 0; i 100; i++) {

   int num = new Random().nextInt(3);

   String classPath = "";

   switch (num){

   case 0:

   classPath = "java.util.Date";

   break;

   case 1:

   classPath = "java.lang.Object";

   break;

   case 2:

   classPath = "com.Tang.reflect.Person";

   break;

   Object obj = null;

   try {

   obj = getInstance(classPath);

   System.out.println(obj);

   } catch (Exception e) {

   e.printStackTrace();

   创建一个指定类的对象

   classPath:指定类的全类名

   public Object getInstance(String classPath) throws Exception{

   Class clazz = Class.forName(classPath);

   return clazz.newInstance();

  

 

  运行结果图

  8.获取当前运行时类的属性结构

  点击查看代码

  

 //获取运行时类的属性结构

 

   @Test

   public void test(){

   Class clazz = Person1.class;

   //获取属性结构,getFileds():获取当前运行时类及其父类中声明为public访问权限的属性

   Field[] fields = clazz.getFields();

   for(Field f : fields){

   System.out.println(f);

   System.out.println("============");

   //getDeclaredFields():获取当前运行时类中声明的所有属性(不包含父类中声明的属性)

   Field[] declaredFields = clazz.getDeclaredFields();

   for(Field f : declaredFields){

   System.out.println(f);

  

 

  运行结果图

  9.获取当前运行时类的方法结构

  点击查看代码

  

//获取运行时类的方法

 

   @Test

   public void test1(){

   Class clazz = Person1.class;

   //getMethods():获取当前运行时类及其所有父类中声明为public权限的方法

   Method[] methods = clazz.getMethods();

   for(Method f : methods){

   System.out.println(f);

   System.out.println("==============");

   //getDeclaredMethods():获取当前运行时类中声明的所有方法(不包含父类中声明的方法)

   Method[] declaredMethods = clazz.getDeclaredMethods();

   for(Method f : declaredMethods){

   System.out.println(f);

  

 

  运行结果图

  10.调用运行时类的指定结构(重点)

  (1)调用私有属性

  点击查看代码

  

 @Test

 

   public void FieldTest() throws Exception {

   Class clazz = Person1.class;

   //创建运行时类的对象

   Object p = clazz.newInstance();

  
/*方式一:(通常不用)

   1.获取指定属性的值:要求运行时类中属性声明为public(通常不采用此方法)

   Field age = clazz.getField("age");

   /*2.设置当前属性的值

   set():参数1:指明设置那个对象的属性 参数2:将此属性值设置为多少*/

   age.set(p,10);

   //3.获取当前属性的值 get():参数1:获取那个对象的当前属性值

   int pAge = (int)age.get(p);

   System.out.println(pAge);

   //方式二:

   //1.getDeclaredField(String fieldName:获取运行时类中指定变量名的属性

   Field name = clazz.getDeclaredField("name");

   //2.保证当前属性是可以访问的

   name.setAccessible(true);

   //3.获取、设置指定对象的此属性值

   name.set(p,"Twq");

   System.out.println(name.get(p));

  

 

  运行结果图

  (2)调用私有方法

  点击查看代码

  

 @Test

 

   public void MethodTest() throws Exception {

   Class clazz = Person1.class;

   Person1 p = (Person1) clazz.newInstance();

   1.获取指定的某个方法

   getDeclareMethod():参数1:指明获取方法的名称 参数2:指明获取的方法的形参列表

   Method show = clazz.getDeclaredMethod("show");

   //2.保证当前方法是可访问的

   show.setAccessible(true);

   //3.调用方法的invoke():参数1:方法的调用者 参数2:给方法形参赋值的实参

   //invoke()的返回值即为对应类中调用的方法的返回值

   show.invoke(p);

   //调用静态方法

   Method showDesc = clazz.getDeclaredMethod("showDesc");

   showDesc.setAccessible(true);

   Object returnVal1 = showDesc.invoke(p);

   System.out.println(returnVal1);//因为返回值为空所以为null

  

 

  运行结果图

  以上就是注解与反射(注解与反射restaurant类)的详细内容,想要了解更多 注解与反射的内容,请持续关注盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: