java 反射 取stream_Java的反射机制

一、反射机制

1、反射的定义:

在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的功能就称为java语言的反射机制。通俗点讲,通过反射,该类对我们来说是完全透明的,想要获取任何东西都可以。

2、关于Class(类)

(1)  Class是一个类,一个描述类的类(也就是描述类本身),封装了描述方法(Method),描述字段的(Filed),描述构造器的(Constructor)等属性。

(2)  对象反射可以得到的信息:某个类的数据成员名、方法和构造器、某个类到底实现了哪些接口。

(3)  对于每个类而言,JRE 都为其保留一个不变的 Class 类型的对象。 一个 Class 对象包含了特定某个类的有关信息。

(4)Class 对象只能由系统建立对象。

(5)  一个类在 JVM 中只会有一个Class实例。

栗子:创建一个类。

public classPerson {

String name;private intage;publicPerson() {

System.out.println("无参构造器");

}public Person(String name, intage) {

System.out.println("有参构造器");this.name =name;this.age =age;

}publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}public intgetAge() {returnage;

}public void setAge(intage) {this.age =age;

}

@OverridepublicString toString() {return "Person{" +

"name='" + name + '\'' +

", age=" + age +

'}';

}

}

3、获取反射机制类的三种方法:

想要使用反射机制,就必须要先获取到该类的字节码文件对象(.class),通过字节码文件对象,就能够通过该类中的方法获取到我们想要的所有信息(方法,属性,类名,父类名,实现的所有接口等等),每一个类对应着一个字节码文件也就对应着一个Class类型的对象,也就是字节码文件对象。获取字节码文件对象[反射对象]的三种方式:

1、通过Class类中的静态方法forName,直接获取到一个类的字节码文件对象,此时该类还是源文件阶段,并没有变为字节码文件。

Class clazz1 = Class.forName("全限定类名");

2、当类被加载成.class文件时,此时Person类变成了.class,在获取该字节码文件对象,也就是获取自己, 该类处于字节码阶段。

Class clazz2 = Person.class;

3、通过类的实例获取该类的字节码文件对象,该类处于创建对象阶段

Class clazz3 = p.getClass();

@Testpublic void testGetClass() throwsClassNotFoundException {

Class clazz= null;//1 通过全类名获取,用的比较多,但可能抛出ClassNotFoundException异常

clazz = Class.forName("com.java.reflection.Person");

System.out.println("通过全类名获取: " +clazz);//1 直接通过类名.Class的方式得到

clazz = Person.class;

System.out.println("通过类名: " +clazz);//2 通过对象的getClass()方法获取,这个使用的少(一般是传的是Object,不知道是什么类型的时候才用)

Object p = newPerson();

clazz=p.getClass();

System.out.println("通过getClass(): " +clazz);

}

4、利用newInstance创建对象:调用的类必须有无参的构造器。

@Testpublic voidtestNewInstance()throwsClassNotFoundException, IllegalAccessException, InstantiationException {

Class clazz= Class.forName("com.java.reflection.Person");//使用Class类的newInstance()方法创建类的一个对象//实际调用的类的那个 无参数的构造器(这就是为什么写的类的时候,要写一个无参数的构造器,就是给反射用的)//一般的,一个类若声明了带参数的构造器,也要声明一个无参数的构造器

Object obj =clazz.newInstance();

System.out.println(obj);

}

5、ClassLoader类加载器

8421da8ab435c686c0c557a764582f64.png

//ClassLoader类装载器

@Testpublic void testClassLoader1() throwsClassNotFoundException, IOException {//1、获取一个系统的类加载器

ClassLoader classLoader =ClassLoader.getSystemClassLoader();

System.out.println("系统的类加载器-->" +classLoader);//2、获取系统类加载器的父类加载器(扩展类加载器(extensions classLoader))

classLoader =classLoader.getParent();

System.out.println("扩展类加载器-->" +classLoader);//3、获取扩展类加载器的父类加载器//输出为Null,无法被Java程序直接引用

classLoader =classLoader.getParent();

System.out.println("启动类加载器-->" +classLoader);//4、测试当前类由哪个类加载器进行加载 ,结果就是系统的类加载器

classLoader = Class.forName("com.java.reflection.Person").getClassLoader();

System.out.println("当前类由哪个类加载器进行加载-->"+classLoader);//5、测试JDK提供的Object类由哪个类加载器负责加载的

classLoader = Class.forName("java.lang.Object").getClassLoader();

System.out.println("JDK提供的Object类由哪个类加载器加载-->" +classLoader);

}

5.1 getResourceAsStream方法

@Testpublic void testGetResourceAsStream() throwsClassNotFoundException, IOException {//5、关于类加载器的一个主要方法//调用getResourceAsStream 获取类路径下的文件对应的输入流

InputStream in = this.getClass().getClassLoader()

.getResourceAsStream("com/java/reflection/test.properties");

System.out.println("in: " +in);

Properties properties= newProperties();

properties.load(in);

String driverClass= properties.getProperty("dirver");

String jdbcUrl= properties.getProperty("jdbcUrl");//中文可能会出现乱码,需要转换一下

String user = new String(properties.getProperty("user").getBytes("ISO-8859-1"), "UTF-8");

String password= properties.getProperty("password");

System.out.println("diverClass: "+driverClass);

System.out.println("user: " +user);

}

6、invoke方法

1 public classPersonInvoke {2 publicPersonInvoke() {3 }4

5 privateString method2() {6 return "Person private String method2";7 }8 }

1 public class StudentInvoke extendsPersonInvoke{2 private voidmethod1(Integer age) {3 System.out.println("Student private void method1, age=:" +age);4 }5 }

1 /**

2 * 获取当前类的父类中定义的私有方法3 * 直接调用getSuperclass()4 */

5 @Test6 public void testGetSuperClass() throwsException {7

8 String className = "com.java.reflection.StudentInvoke";9

10 Class clazz =Class.forName(className);11 Class superClazz =clazz.getSuperclass();12

13 System.out.println(superClazz);14 //输出结果:class com.java.reflection.PersonInvoke

15 }

7、构造器(Constructor)

/*** 构造器:开发用的比较少*/@Testpublic void testConstructor() throwsClassNotFoundException, NoSuchMethodException,

IllegalAccessException, InvocationTargetException, InstantiationException {

String className= "com.java.reflection.Person";

Class clazz = (Class) Class.forName(className);//1.获取Constructor对象

Constructor[] constructors =(Constructor[]) Class.forName(className).getConstructors();//遍历

for (Constructorconstructor: constructors) {

System.out.println(constructor);

}

Constructor constructor = clazz.getConstructor(String.class, Integer.class);

System.out.println("指定的-->" +constructor);//2.调用构造器的newInstance()方法创建对象

Object obj= constructor.newInstance("changwen", 11);

}

8、注解(Annotation)

基本的 Annotation

• 使用 Annotation时要在其前面增加@符号,并把该Annotation 当成一个修饰符使用.用于修饰它支持的程序元素

• 三个基本的Annotation:

–@Override:限定重写父类方法,该注释只能用于方法

–@Deprecated:用于表示某个程序元素(类,方法等)已过时

–@SuppressWarnings:抑制编译器警告.

@Retention(RetentionPolicy.RUNTIME) //运行时检验

@Target(value = {ElementType.METHOD}) //作用在方法上

public @interfaceAgeValidator {intmin();intmax();

}

1 /**

2 * 通过反射才能获取注解3 */

4 @Test5 public void testAnnotation() throwsException {6

7 //这样的方式不能使用注解

8 /**Person3 person3 = new Person3();9 person3.setAge(10);*/

10

11 String className = "com.java.reflection.Person3";12 Class clazz =Class.forName(className);13 Object obj =clazz.newInstance();14

15 Method method = clazz.getDeclaredMethod("setAge",Integer.class);16 int val =40;17

18 //获取注解

19 Annotation annotation = method.getAnnotation(AgeValidator.class);20 if (annotation != null){21 if (annotation instanceofAgeValidator){22 AgeValidator ageValidator =(AgeValidator) annotation;23

24 if (val< ageValidator.min() || val>ageValidator.max()){25 throw new RuntimeException("数值超出范围");26 }27 }28 }29

30 method.invoke(obj, val);31 System.out.println(obj);32 }

原文转载于:https://www.cnblogs.com/bojuetech/p/5896551.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值