您的位置:首页 > 新闻 > 热点要闻 > 中国纪检监察报网站_网站开发与管理心得体会_手机端百度收录入口_百度指数有哪些功能

中国纪检监察报网站_网站开发与管理心得体会_手机端百度收录入口_百度指数有哪些功能

2024/12/23 3:05:39 来源:https://blog.csdn.net/LB_Wuyanzu/article/details/143451101  浏览:    关键词:中国纪检监察报网站_网站开发与管理心得体会_手机端百度收录入口_百度指数有哪些功能
中国纪检监察报网站_网站开发与管理心得体会_手机端百度收录入口_百度指数有哪些功能

Java高级——反射

  • Class类与获取Class实例
    • 1、关于java.long.Class的理解
    • 2、获取Class实例的四种方法
  • 创建运行时类的对象
  • 获取运行时类的结构
    • 1、获取运行时类的属性
    • 2、获取运行时类的方法结构
    • 3、获取运行时类的构造器结构
  • 调用运行时类的指定结构
    • 1、调用运行时类的属性
    • 2、调用运行时类的方法
    • 3、调用运行时类的构造方法

Class类与获取Class实例

一般来说,Class类是反射的源头,在进行反射操作之前,都要获取Class实例。

Person.java

package com.atguigu.java;public class Person {private int id;int age;public String name;}  //省略构造方法、get、set、toString

1、关于java.long.Class的理解

1)类的加载过程:
程序经过javac.exe命令以后,会生成一个或多个字节码文件(.cLass结尾)。
接着我们使用java.exe命令对某个字节码文件进行解释运行。相当于将某个字节码文件加载到内存中。此过程就称为类的加载。加载到内存中的类,我们就称为运行时类,此运行时类,就作为CLass的一个实例。
2)换句话说,CLass的实例就对应着一个运行时类(Class的实例不能主动创建new一个出来)。
万事万物皆对象对象.xxx, File, URL,反射,前端、数据库操作等都是对象
3)加载到内存中的运行时类,会缓存一定时间。此时我们可以通过不同方法获取此运行时类。

2、获取Class实例的四种方法

ReflectionTest.java

package com.atguigu.java;import org.junit.Test;public class ReflectionTest {@Testpublic void test3() throws ClassNotFoundException {//方式一 调用运行时类的属性: .class//Class<Person> clazz1 = Person.class;Class clazz1 = Person.class;//方式二 调用class的静态方法 forName(String classpath)Class clazz2 = Class.forName("com.atguigu.java.Person");//方式三  通过运行时类的对象Person p1 = new Person();Class clazz3 = p1.getClass();//方式四 使用类的加载器ClassLoaderClassLoader classLoader = ReflectionTest.class.getClassLoader();Class clazz4 = classLoader.loadClass("com.atguigu.java.Person");System.out.println(clazz4 == clazz1);//不同方式获取的运行时的类是一样的。输出结果为True}
}

创建运行时类的对象

通过newInstance() 方法创建运行时类的对象。

NewInstanceTest.java

package com.atguigu.java;import org.junit.Test;public class NewInstanceTest {@Testpublic void test() throws IllegalAccessException, InstantiationException {Class clazz = Person.class;//Object obj = clazz.newInstance();   输出是一个Person对象,可强转为PersonPerson obj = (Person) clazz.newInstance();}
}

newInstance() 方法内部通过Person的无参构造方法(空参构造器)创建对象,可以理解为一切创建对象的方法都要去调用无参构造。
通过上面test方法抛出的两个异常,可以了解,如果想通过newInstance() 创建对象,必须满足两个要求:

  • 运行时类必须提供无参构造器
  • 无参构造器的访问权限要足够(public)

从而得知,在javabean中要求提供一个public的空参构造器。原因: 1.便于通过反射,创建运行时类的对象。2.便于子类继承此运行时类时,默认调用super()时,保证父类有此构造器。

获取运行时类的结构

1、获取运行时类的属性

在这里插入图片描述
Class实例的getFields() 方法,
getFields(): 获取当前运行时类及其父类中声明为public访问权限的属性
getDeclaredFields(): 获取当前运行时类中声明的所有属性(不包含父类中声明的属性)。

FieldTest.java

public class FieldTest {@Testpublic void test1(){Class<Person> clazz = Person.class;//获取属性结构//getFields():获取当前运行时类及其父类中声明为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);}}
}

2、获取运行时类的方法结构

getMethods()

public class MethodTest {@Testpublic void test1() {Class<Person> clazz = Person.class;// getMethods():获取当前运行时类及其所有父类中声明为public权限的方法Method[] methods = clazz.getMethods();for (Method m : methods) {System.out.println(m);}System.out.println();// getDeclaredMethods():获取当前运行时类中声明的所有方法。(不包含父类中声明的方法)Method[] declaredMethods = clazz.getDeclaredMethods();for (Method m : declaredMethods) {System.out.println(m);}}
}

3、获取运行时类的构造器结构

getConstructors()

public class ConstructorTest {public void test1() {Class clazz = Person.class;//getconstructors():获取当前运行时类中声明为public的构造器Constructor[ ] constructors = clazz.getConstructors();for(Constructor c : constructors) {System.out.println(c);}System.out.println();//getDeclaredConstructors():获取当前运行时类中声明的所有的构造器Constructor[] declaredConstructors = clazz.getDeclaredConstructors();for( Constructor c : declaredConstructors){System.out.println(c);}}
}

调用运行时类的指定结构

1、调用运行时类的属性

getField() 和 getDeclaredField()
在这里插入图片描述
不常用的方法(获取指定属性:要求运行时类中的属性为public):

public class ReflectionTest {@Testpublic void test() throws Exception {Class clazz = Person.class;//创建运行时类的对象Person p = (Person) clazz.newInstance();//获取指定属性:要求运行时类中的属性为public//通常不采用此方法!Field name = clazz.getField("name");//设置当前属性的值name.set(p,"Tom");//获取String n = (String) name.get(p);System.out.println(n);}
}

常用的方法 getDeclaredField()

@Testpublic void test2() throws Exception {Class clazz = Person.class;//创建运行时类的对象Person p = (Person) clazz.newInstance();//获取指定属性Field name = clazz.getDeclaredField("name");//保证当前属性是可访问的(例如private时)  很重要!!!!name.setAccessible(true);//设置当前属性的值name.set(p,"Tom");//获取String n = (String) name.get(p);System.out.println(n);}

2、调用运行时类的方法

首先为Person创建一个方法:

public class Person {private int id;int age;public String name;private  String showName(String name){System.out.println(name);return name;}}
@Testpublic void test3() throws Exception {Class clazz = Person.class;//创建运行时类的对象Person p = (Person) clazz.newInstance();//获取指定某个方法,clazz.getDeclaredMethod()://参数1:指明获取方法的名称 参数2:指明获取方法的形参列表Method showName = clazz.getDeclaredMethod("showName", String.class);//保证方法是可访问的showName.setAccessible(true);//invoke反过来调用方法。//参数1:方法的调用者(谁的方法)  参数2:给方法形参赋值的实参//invoke方法的返回值就是被调用的方法的返回值showName.invoke(p,"Tom");}

3、调用运行时类的构造方法

@Testpublic void test4() throws Exception {Class clazz = Person.class;//创建运行时类的对象Person p = (Person) clazz.newInstance();//获取指定的构造器Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class);//保证可访问declaredConstructor.setAccessible(true);//调用构造器创建对象Person tom = (Person) declaredConstructor.newInstance("Tom");}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com