100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 韩顺平Java自学笔记 反射

韩顺平Java自学笔记 反射

时间:2018-10-24 00:50:42

相关推荐

韩顺平Java自学笔记 反射

一。反射入门案例

目录

一。反射入门案例

二。反射的机制

1.反射的原理

2.反射相关的类

3.反射的优点和缺点

三。Class类详解

1.Class类的特征

2.Class的常用方法

3.获取Class对象的六种方法

4.那些类型有Class对象

四。类加载

1.动态加载和静态加载

2.类的加载流程

3.获取类的结构信息

4.反射爆破

五。课后的作业

1.课后作业1

2.课后作业2

提出一个问题,如何修改外部的配置文件,来操控java内部代码的执行逻辑。

反射类

ReflectionQuestion

package com.hspaidu.reflection.qusetion;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.Properties;public class ReflectionQuestion {public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {// 使用properties类可以引入外部文件Properties properties = new Properties();properties.load(new FileInputStream("src\\re.properties"));// 获得class的全部路径String classfullpath = properties.get("classfullpath").toString();// 得到对象的方法String method = properties.get("method").toString();System.out.println("method = "+method);System.out.println("classfullpath = " + classfullpath);//返回了一个class类的类对象Class cls = Class.forName(classfullpath);//通过cls得到对象的实例 可以不用强转也是cat类型Object o = cls.newInstance();System.out.println("o的运行类型 = "+o.getClass());// 得到类当中cls的方法的对象 方法也是对象Method method1 = cls.getMethod(method);// 通过方法的对象来调用类实例当中的方法method1.invoke(o); // 方法.invoke(对象)}}

运行结果

method = hi

classfullpath = com.hspaidu.Cat

o的运行类型 = class com.hspaidu.Cat

Hi 招财猫

被操作的类

Cat

package com.hspaidu;public class Cat {private String name = "招财猫";public void hi(){System.out.println("Hi "+name);}public void cry(){System.out.println(name+" 在cry");}}

配置文件

re.properties

classfullpath = com.hspaidu.Catmethod = hi

修改外部文件

classfullpath = com.hspaidu.Catmethod = cry

反射类输出结果

method = cry

classfullpath = com.hspaidu.Cat

o的运行类型 = class com.hspaidu.Cat

招财猫 在cry

二。反射的机制

1.反射的原理

Class当中有一些api可以获取类相关的一些信息,比如实例,方法,全类名等。

所有的类在堆中都有一个复制体,我们可以通过操作这个复制体,来使用这个类。

原理图

描述:Java程序加载有三个阶段

编译阶段:类有属性和方法,构造器。Cat有hi方法,源代码当中会体现,经过Javac的编译,得到一个Cat.class字节码文件,会有属性,方法,构造器等等,

类的加载阶段:字节码文件会加载到加载区域。将class类对象放到堆当中。字节码文件到堆当中是使用了类加载器的classLoader的,类加载器就体现了反射机制。在底层,已经将放在堆当中对象的属性看成可以操作的对象了。类加载完之后生成对象。该对象知道他是属于那个class对象的。得到class对象之后,就可以对对象进行操作了。

运行阶段:调用Cat cat = new Cat(); cat.hi() 会导致类的加载

2.反射相关的类

代码演示

package com.hspaidu.reflection;import java.io.FileInputStream;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.util.Properties;public class Reflection01 {public static void main(String[] args) throws Exception {Properties properties = new Properties();properties.load(new FileInputStream("src\\re.properties"));String classfullpath = properties.get("classfullpath").toString();String method = properties.get("method").toString();System.out.println("method = "+method);System.out.println("classfullpath = " + classfullpath);//关于Class对象Class cls = Class.forName(classfullpath);//并没有进行类型的强转Object o = cls.newInstance();System.out.println(o.getClass());// 关于方法Method method1 = cls.getMethod(method);method1.invoke(o);//关于属性Field age = cls.getField("age"); //不能得到私有的属性System.out.println("年龄"+age.get(o)); //反射反射,反过来的: 成员变量对象.get(对象)//关于构造器Constructor constructor = cls.getConstructor(); //后边没有参数,返回的是无参的构造器System.out.println(constructor); //没有形参的构造器Constructor constructor1 = cls.getConstructor(String.class); //传入的是String的Class对象System.out.println(constructor1); //有形参的构造器}}

结果

method = cry

classfullpath = com.hspaidu.Cat

class com.hspaidu.Cat

招财猫 在cry

年龄10

public com.hspaidu.Cat()

public com.hspaidu.Cat(java.lang.String)

3.反射的优点和缺点

实例

Reflection02

package com.hspaidu.reflection;import com.hspaidu.Cat;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class Reflection02 {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {m1();m2();}// 传统的方法来调用hi方法public static void m1(){Cat cat = new Cat();long start = System.currentTimeMillis();for (int i=0;i<9000000;i++){cat.hi();}long end = System.currentTimeMillis();System.out.println("传统方法调用 hi 耗时 = "+(end-start));}// 反射机制调用public static void m2() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {Class aClass = Class.forName("com.hspaidu.Cat");Method hi = aClass.getMethod("hi");Object o = aClass.newInstance();long start = System.currentTimeMillis();for (int i=0;i<9000000;i++){hi.invoke(o);}long end = System.currentTimeMillis();System.out.println("反射方法调用 hi 耗时 = "+(end-start));}}

记得把控制台输出语句关了,太耗时间。

结果

传统方法调用 hi 耗时 = 3

反射方法调用 hi 耗时 = 20

进行优化

Reflection02类

package com.hspaidu.reflection;import com.hspaidu.Cat;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class Reflection02 {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {m1();m2();m3();}// 传统的方法来调用hi方法public static void m1() {Cat cat = new Cat();long start = System.currentTimeMillis();for (int i = 0; i < 9000000; i++) {cat.hi();}long end = System.currentTimeMillis();System.out.println("传统方法调用 hi 耗时 = " + (end - start));}// 反射机制调用public static void m2() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {Class aClass = Class.forName("com.hspaidu.Cat");Method hi = aClass.getMethod("hi");Object o = aClass.newInstance();long start = System.currentTimeMillis();for (int i = 0; i < 9000000; i++) {hi.invoke(o);}long end = System.currentTimeMillis();System.out.println("反射方法调用 hi 耗时 = " + (end - start));}// 反射优化,取消访问机制public static void m3() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {Class aClass = Class.forName("com.hspaidu.Cat");Method hi = aClass.getMethod("hi");hi.setAccessible(true);Object o = aClass.newInstance();long start = System.currentTimeMillis();for (int i = 0; i < 9000000; i++) {hi.invoke(o);}long end = System.currentTimeMillis();System.out.println("优化后反射方法调用 hi 耗时 = " + (end - start));}}

优化结果

传统方法调用 hi 耗时 = 3

反射方法调用 hi 耗时 = 24

优化后反射方法调用 hi 耗时 = 17

优化的幅度并不大

三。Class类详解

1.Class类的特征

类图

Class是被系统创建出来的。

相同的类,只有一个class对象

public class Class01 {public static void main(String[] args) throws ClassNotFoundException {// 对于相同的Class,在内存中只有一份Class cls1 = Class.forName("com.hspaidu.Cat");Class cls2 = Class.forName("com.hspaidu.Cat");System.out.println("哈希值 :"+cls1.hashCode());System.out.println("哈希值 :"+cls2.hashCode());Class cls3 = Class.forName("com.hspaidu.Dog");System.out.println("dog哈希值:"+cls3.hashCode());// 对象实例知道自己是那个class类对象的实现}}

运行结果

哈希值 :1735600054

哈希值 :1735600054

dog哈希值:21685669

对象实例知道自己是那个class类对象的实现

2.Class的常用方法

Class02类

package com.hspaidu.reflection.class_;import com.hspaidu.Car;import java.lang.reflect.Field;public class Class02 {public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {// 获取到了Car类的Class对象,根据全路径String classAllPath = "com.hspaidu.Car";//<?>不知道属于哪个类Class<?> aClass = Class.forName(classAllPath);System.out.println(aClass); //是属于那个类的class对象System.out.println(aClass.getClass()); //输出他的运行类型System.out.println(aClass.getPackage().getName()); //z得到类对象包的名字System.out.println(aClass.getName()); //得到一个全类名//对象Car car = (Car)aClass.newInstance(); //创建一个对象实例System.out.println(car);//创建一个属性实例 获得字段的值 但不能是私有的属性Field brand = aClass.getField("brand");System.out.println(brand.get(car));//修改指定对象的属性值brand.set(car,"奔驰");System.out.println(brand.get(car));System.out.println(brand.getName());System.out.println();//获取所有字段的名称Field[] fields = aClass.getFields();for (Field a: fields){System.out.println(a.getName());}}}

运行结果

class com.hspaidu.Car

class java.lang.Class

com.hspaidu

com.hspaidu.Car

Car{brand='宝马', price=50, color='red'}

宝马

奔驰

brand

brand

price

color

3.获取Class对象的六种方法

在程序的不同阶段可以用不同的方式得到Class的类对象,编译阶段,类加载阶段,运行阶段,在类加载器处获得。

代码

package com.hspaidu.reflection.class_;import com.hspaidu.Car;public class GetClass {public static void main(String[] args) throws ClassNotFoundException {//编译阶段获得 多用于配置文件的到类的全路径使用 xml文件 框架的底层使用String classAllPath = "com.hspaidu.Car";Class<?> cls1= Class.forName(classAllPath);System.out.println(cls1);//类加载阶段获得 类名.class//多用于参数的传递//Constructor constructor1 = cls.getConstructor(String.class); 例如这行代码Class cls2 = Car.class;System.out.println(cls2);//运行阶段获得 对象.class 所以说每一个对象知道他的Class类是什么Car car = new Car();Class cls3 = car.getClass();System.out.println(cls3);//通过类加载器获得 有四种类加载器 JVM会讲ClassLoader classLoader = car.getClass().getClassLoader();Class cls4 = classLoader.loadClass(classAllPath);System.out.println(cls4);System.out.println(cls1.hashCode());System.out.println(cls2.hashCode());System.out.println(cls3.hashCode());System.out.println(cls4.hashCode());//基本类的封装Class<Integer> integerClass = int.class;Class<Double> doubleClass = double.class;Class<Character> characterClass = char.class;System.out.println(integerClass); //输出int 有一个自动装箱和一个自动拆箱的过程//基本类型的TYPE属性的到Class<Integer> type = Integer.TYPE;Class<Character> type1 = Character.TYPE;Class<Double> type2 = Double.TYPE;System.out.println(type);//两种方式获得的基本类型的Class是同一个System.out.println(integerClass.hashCode());System.out.println(type.hashCode());}}

运行结果

class com.hspaidu.Car

class com.hspaidu.Car

class com.hspaidu.Car

class com.hspaidu.Car

1735600054

1735600054

1735600054

1735600054

int

int

21685669

21685669

4.那些类型有Class对象

代码

package com.hspaidu.reflection.class_;import java.io.Serializable;public class AllTypeClass {public static void main(String[] args) {Class<String> cls = String.class;//外部类Class<Serializable> cls1 = Serializable.class;//接口Class<Integer[]> cls2 = Integer[].class;//数组Class<Integer[][]> cls3 = Integer[][].class;//二维数组Class<Deprecated> cls4 = Deprecated.class;//注解Class<Thread.State> cls5 = Thread.State.class; //枚举Class<Long> cls6 = long.class; //基本数据类型Class<Void> cls7 = void.class; //返回类型Class<Class> cls8 = Class.class; System.out.println(cls);System.out.println(cls1);System.out.println(cls2);System.out.println(cls3);System.out.println(cls4);System.out.println(cls5);System.out.println(cls6);System.out.println(cls7);System.out.println(cls8);}}

运行结果

class java.lang.String

interface java.io.Serializable

class [Ljava.lang.Integer;

class [[Ljava.lang.Integer;

interface java.lang.Deprecated

class java.lang.Thread$State

long

void

class java.lang.Class

四。类加载

1.动态加载和静态加载

静态加载:编译时会校验所有的类,动态加载:在运行的时候,没有运行这个类就不会报错

反射是动态加载,执行到的时候才会报错。直接new是静态加载,直接在编译时期就会检测你类的合法性。

错误是一直存在的,就是有没有发现,不过静态加载生成不了class文件,过不了编译,动态可以。

2.类的加载流程

流程图

加载

将class文件读入内存,并创建一个Class对象

链接

分为三部分,验证,准备,解析。

初始化

可以由程序员控制前两个是JVM自动完成的。主要是静态成员,与对象无关,是类的加载阶段,而不是对象创建阶段。

类加载的五个阶段

加载

讲二进制放到方法区,并生成Class类。

验证

准备

举例

package com.hspaidu.reflection.classload;public class ClassLoad02 {public static void main(String[] args) {}}class A{//属性-字段-成员变量// n1是实例变量,在准备的时候不会进行处理,public int n1 = 10;// n2是静态变量,分配内存,但是默认初始化,值为0public static int n2 = 20;// 是常量,不是静态变量,一旦赋值就不会改变,所以会赋值为20public static final int n3 = 30;}

解析

加载的时候,还没有真正的放在内存当中,按符号来记录。常量池内的符号引用,就像是你的小名,只有你的家人朋友会使用,适合小范围索引。直接引用为你具体的名字,在哪里都是通过用的,适合在大的范围当中索引。

一个是A类B类,相对位置表示,一个是经纬度表示。

仍然是处理静态代码块,而不是具体的实例。

在进行类加载的时候,因为这个机制,才能保证某个类在内存中只有一份Class对象。

再进行深入就是JVM的底层了

3.获取类的结构信息

第一组

7.不返回父类的构造器

第二组

第三组

第四组

api的代码

package com.hspaidu.reflection.qusetion;import org.junit.Test;import java.lang.annotation.Annotation;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;//演示如何通过Api获得类的结构信息。 如果你可以拿到一个类的Class对象,你基本上就可以得到该类所有的对象信息了public class ReflectionUtils {public static void main(String[] args) {}@Testpublic void api_01() throws ClassNotFoundException, NoSuchMethodException {// 得到Class的对象Class<?> aClass = Class.forName("com.hspaidu.reflection.qusetion.Person");//getName() 获得类的全类名System.out.println(aClass.getName());//getSimpleName() 获取简单类名System.out.println(aClass.getSimpleName());//getFields()获得所有的本类及父类的属性 只能达到公开的Field[] fields = aClass.getFields();for (Field field : fields) {System.out.println("本类及父类的属性 = " + field.getName());}//getDeclaredFields() 公开的私有的都可以的到Field[] declaredFields = aClass.getDeclaredFields();for (Field declaredField : declaredFields) {System.out.println("所有的详细的属性 = " + declaredField.getName());}// getMethods() 获得本类和父类的方法 只得到公开的 父类的父类也可以Method[] methods = aClass.getMethods();for (Method method : methods) {System.out.println("父类及子类的方法名 = " + method.getName()); //得到的事公开的方法}//获得本类当中所有的方法Method[] declaredMethod = aClass.getDeclaredMethods();for (Method method : declaredMethod) {System.out.println("所有的方法 = " + method.getName());//只有类的}//getConstructors() 公开的 得到本类当中的构造方法Constructor<?>[] constructor = aClass.getConstructors();for (Constructor<?> constructor1 : constructor) {System.out.println("本类及父类的构造方法" + constructor1);}//得到本类所有的构造器名称,包括私有的Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors();for (Constructor<?> declaredConstructor : declaredConstructors) {System.out.println("输出构造器的名字" + declaredConstructor.getName()); //这里只是输出名字}}// 字段当中包含的方法@Testpublic void api_02() throws ClassNotFoundException {Class<?> aClass = Class.forName("com.hspaidu.reflection.qusetion.Person");// getDeclaredFields() 本类及父类的属性Field[] declaredFields = aClass.getDeclaredFields();for (Field declaredField : declaredFields) {System.out.println("所有的详细的属性 = " + declaredField.getName() + "所有属性类型的值为 = " + declaredField.getModifiers()+ "该属性的类型 = " + declaredField.getType());}//获得本类当中所有的Method[] declaredMethod = aClass.getDeclaredMethods();for (Method method : declaredMethod) {System.out.println("该方法的方法名 = " + method.getName() + "该方法修饰符的值为 = " + method.getModifiers()+ "该方法的返回值类型 = " + method.getReturnType());//只有类的// 获得所有方法的参数类型Class<?>[] parameterTypes = method.getParameterTypes();for (Class<?> parameterType : parameterTypes) {System.out.println("参数类型为" + parameterType);}}// 返回一个父类的全路径System.out.println(aClass.getSuperclass());//获得接口的信息Class<?>[] interfaces = aClass.getInterfaces();for (Class<?> anInterface : interfaces) {System.out.println("接口的信息 " + anInterface);}// 获得注解的信息Annotation[] annotations = aClass.getAnnotations();for (Annotation annotation : annotations) {System.out.println("注解信息 " + annotation);}Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors();for (Constructor<?> declaredConstructor : declaredConstructors) {System.out.println("构造方法的名字 "+declaredConstructor.getName());Class<?>[] parameterTypes = declaredConstructor.getParameterTypes();for (Class<?> parameterType : parameterTypes) {System.out.println("改构造器的形参类型 "+parameterType);}}}}class A {public String hobby;public void hi() {}}interface IA {}interface IB {}@Deprecatedclass Person extends A implements IA, IB {// 不同访问权限的属性public String name;protected int age;String job;private static double sal;public Person() {}public Person(int age) {this.age = age;}public Person(int age, String job) {this.age = age;this.job = job;}// 不同访问权限的方法public void m1(String name, String job, int age) {}private void m2() {}protected void m3() {}void m4() {}}

运行的结果api_01

com.hspaidu.reflection.qusetion.Person

Person

本类及父类的属性 = name

本类及父类的属性 = hobby

所有的详细的属性 = name

所有的详细的属性 = age

所有的详细的属性 = job

所有的详细的属性 = sal

父类及子类的方法名 = m1

父类及子类的方法名 = hi

父类及子类的方法名 = wait

父类及子类的方法名 = wait

父类及子类的方法名 = wait

父类及子类的方法名 = equals

父类及子类的方法名 = toString

父类及子类的方法名 = hashCode

父类及子类的方法名 = getClass

父类及子类的方法名 = notify

父类及子类的方法名 = notifyAll

所有的方法 = m1

所有的方法 = m2

所有的方法 = m4

所有的方法 = m3

本类及父类的构造方法public com.hspaidu.reflection.qusetion.Person(int,java.lang.String)

本类及父类的构造方法public com.hspaidu.reflection.qusetion.Person(int)

本类及父类的构造方法public com.hspaidu.reflection.qusetion.Person()

输出构造器的名字com.hspaidu.reflection.qusetion.Person

输出构造器的名字com.hspaidu.reflection.qusetion.Person

输出构造器的名字com.hspaidu.reflection.qusetion.Person

运行的结果api_02

所有的详细的属性 = name所有属性类型的值为 = 1该属性的类型 = class java.lang.String

所有的详细的属性 = age所有属性类型的值为 = 4该属性的类型 = int

所有的详细的属性 = job所有属性类型的值为 = 0该属性的类型 = class java.lang.String

所有的详细的属性 = sal所有属性类型的值为 = 10该属性的类型 = double

该方法的方法名 = m1该方法修饰符的值为 = 1该方法的返回值类型 = void

参数类型为class java.lang.String

参数类型为class java.lang.String

参数类型为int

该方法的方法名 = m2该方法修饰符的值为 = 2该方法的返回值类型 = void

该方法的方法名 = m4该方法修饰符的值为 = 0该方法的返回值类型 = void

该方法的方法名 = m3该方法修饰符的值为 = 4该方法的返回值类型 = void

class com.hspaidu.reflection.qusetion.A

接口的信息 interface com.hspaidu.reflection.qusetion.IA

接口的信息 interface com.hspaidu.reflection.qusetion.IB

注解信息 @java.lang.Deprecated()

构造方法的名字 com.hspaidu.reflection.qusetion.Person

改构造器的形参类型 int

改构造器的形参类型 class java.lang.String

构造方法的名字 com.hspaidu.reflection.qusetion.Person

改构造器的形参类型 int

构造方法的名字 com.hspaidu.reflection.qusetion.Person

4.反射爆破

案例

爆破创建实例

代码

package com.hspaidu.reflection.qusetion;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;public class ReflectCreateInstance {public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {// 得到Class对象Class<?> aClass = Class.forName("com.hspaidu.reflection.qusetion.User");//调用的是无参的构造器 创建实例Object o = aClass.newInstance();System.out.println(o);//调用的是带有一个参数的构造器 getConstructor创建的是公开的构造器方法Constructor<?> constructor = aClass.getConstructor(String.class);// 先得到相应的构造器,再传入相应的实参Object hsp = constructor.newInstance("hsp");System.out.println("hsp = "+hsp);//得到私有的构造器对象Constructor<?> constructor1 = aClass.getDeclaredConstructor(int.class,String.class);// 进行爆破访问私有的构造器 可以访问私有的构造方法 在反射面前一切都是纸老虎,留的一个后门constructor1.setAccessible(true);Object xiaowang = constructor1.newInstance(100, "小王");//破坏了数据的封装性System.out.println(xiaowang);}}class User{private int age = 20;private String name = "韩顺平教育";public User(){}public User(String name) {this.name = name;} //public的有参构造器private User(int age, String name) { //private的有参构造器this.age = age;this.name = name;}@Overridepublic String toString() {return "User{" +"age=" + age +", name='" + name + '\'' +'}';}}

运行结果

User{age=20, name='韩顺平教育'}

hsp = User{age=20, name='hsp'}

User{age=100, name='小王'}

访问对象的成员

代码

package com.hspaidu.reflection.qusetion;import java.lang.reflect.Constructor;import java.lang.reflect.Field;public class ReflectAccessProperty {public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException {// 得到类对应的Class对象Class<?> aClass = Class.forName("com.hspaidu.reflection.qusetion.Student");Object o = aClass.newInstance();System.out.println(o.getClass());// 创建字段对象Field age = aClass.getField("age");age.set(o,88); //通过反射来得到他的属性System.out.println(o);System.out.println(age.get(o));// 操作私有的静态属性Field name = aClass.getDeclaredField("name");// 进行强制爆破,操纵私有的属性name.setAccessible(true);name.set(null,"老汉"); //因为name是静态的所以可以是null,算是所有对象的System.out.println(o);System.out.println(name.get(null));}}class Student{public int age;private static String name;public Student(){}@Overridepublic String toString() {return "Student{" +"age=" + age +" name = "+name+'}';}}

运行结果

class com.hspaidu.reflection.qusetion.Student

Student{age=88 name = null}

88

Student{age=88 name = 老汉}

老汉

访问方法

代码

package com.hspaidu.reflection.qusetion;import javax.print.DocFlavor;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class ReflectAccessMethod {public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {// 得到ClassClass<?> aClass = Class.forName("com.hspaidu.reflection.qusetion.Boos");// 创建对象Object o = aClass.newInstance();// 得到方法的对象Method hi = aClass.getMethod("hi",String.class);// 调用方法hi.invoke(o,"韩顺平将java");// 方法的属性当中并没有定义方法返回值的类型 可以拿到私有的方法Method say = aClass.getDeclaredMethod("say", int.class, String.class, char.class);// 这样就可以操作私有的方法了say.setAccessible(true);System.out.println(say.invoke(o,100,"小明",'A'));System.out.println(say.invoke(o,200,"李四",'B'));// 在编译阶段是Object 在返回的时候运行类型为String 接受的时候不知道的 编译的时候才判定Object invoke = say.invoke(o, 200, "李四", 'B');System.out.println(invoke.getClass());}}class Boos{public int age;private static String name;public Boos() {}private static String say(int n,String s,char c){return n+" "+s+" "+c;}public void hi(String s){System.out.println("hi"+s);}}

结果

hi韩顺平将java

100 小明 A

200 李四 B

class java.lang.String

五。课后的作业

1.课后作业1

代码

package com.hspaidu.homework;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class HomeWork01 {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {// 得到类对应的Class对象Class<?> aClass = Class.forName("com.hspaidu.homework.PrivateTest");// 创建一个对象的实例Object o = aClass.newInstance();// 创建一个私有字段的实例Field name = aClass.getDeclaredField("name");// 进行爆破name.setAccessible(true);// 修改私有属性的值name.set(o,"中国");// System.out.println(o);// 得到私有方法的对象Method getName = aClass.getDeclaredMethod("getName");//直接调用方法System.out.println("name属性的值 "+getName.invoke(o));}}class PrivateTest{private String name = "弯弯";public String getName(){return name;}@Overridepublic String toString() {return "PrivateTest{" +"name='" + name + '\'' +'}';}}

结果

中国

2.课后作业2

代码

package com.hspaidu.homework;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class HomeWork02 {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {// 得到file类对象Class<?> aClass = Class.forName("java.io.File");// 得到所有的构造方法Constructor<?>[] declaredConstructor = aClass.getDeclaredConstructors();for (Constructor<?> constructor : declaredConstructor) {System.out.println("File的构造器"+constructor);}// 得到形参为string的构造器Constructor<?> declaredConstructor1 = aClass.getDeclaredConstructor(String.class);// 写入文件的地址String fileAllPath = "d:\\mynew.txt";// 创建文件对象 这是一个返回值 还在内存当中Object file = declaredConstructor1.newInstance(fileAllPath);//得到方法的对象Method createNewFile = aClass.getMethod("createNewFile");createNewFile.invoke(file);//引用文件创建方法System.out.println(file.getClass());System.out.println("创建文件成功 "+ fileAllPath);}}

运行结果

File的构造器public java.io.File(java.lang.String,java.lang.String)

File的构造器public java.io.File(java.lang.String)

File的构造器private java.io.File(java.lang.String,java.io.File)

File的构造器public java.io.File(java.io.File,java.lang.String)

File的构造器public java.io.File(.URI)

File的构造器private java.io.File(java.lang.String,int)

class java.io.File

创建文件成功 d:\mynew.txt

四。其他知识点

反射在泛型当中的应用

代码

package com.map_;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.List;public class Test {public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {List<Integer> list = new ArrayList<>();list.add(12);Method method = list.getClass().getDeclaredMethod("add", Object.class);method.invoke(list, "abc");System.out.println(list);}}

运行结果

[12, abc]

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。