1.简介

1.1 反射:

  • 对于任意一个类,都能够知道这个类中的所有属性和方法
  • 对于任意一个对象,都能够调用它的任意一个方法和属性
  • 这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制
  • 原理:Java语言在编译之后会生成一个class文件,反射就是通过字节码文件找到其类中的方法和属性等;

用一句话总结就是反射可以实现在运行时可以知道任意一个类的属性和方法。

为什么要用反射来获取对象:

  • new属于静态编译
  • 反射属于动态编译,只有到运行时他才会去获得该对象的实例

1.2 反射用到的类

  • 1、Class:类的对象;
  • 2、Constructor:类的构造方法
  • 3、Field:类中的属性对象
  • 4、Method:类中的方法对象

Field:

Field是一个类,位于java.lang.reflect包下。在Java反射中Field类描述的是类的属性信息,功能包括:

  • 获取当前对象的成员变量的类型
  • 对成员变量重新设值

Field 类对象常用方法:

  • 获取变量的类型:

    • Field.getType():返回这个变量的类型
    • Field.getGenericType():如果当前属性有签名属性类型就返回,否则就返回 Field.getType()
    • isEnumConstant() : 判断这个属性是否是枚举类
  • 获取成员变量的修饰符
    • Field.getModifiers() 以整数形式返回由此 Field 对象表示的字段的 Java 语言修饰符
  • 获取和修改成员变量的值
    • getName() : 获取属性的名字
    • get(Object obj) 返回指定对象obj上此 Field 表示的字段的值
    • set(Object obj, Object value) 将指定对象变量上此 Field 对象表示的字段设置为指定的新值

1.3 几种获取class对象的方法:

  • 1.通过ClassLoader对象的loadClass()方法:
    (不会对类进行初始化。)
 ClassLoader.getSystemClassLoader().loadClass("com.my.test.Hello")
  • 2.类名.class
    (仅适合在编译前就已经明确要操作的 Class,同样不会对类进行初始化。)
  Class clazz2 = User.class;
  • 3.Class.forName()
    (前提:已明确类的全路径名。)
    forName0是一个native方法。调用forName(string)方法等同于调用Class.forName(className, true, currentLoader)方法
Class clazz1 = null;
try {clazz1 = Class.forName("com.reflection.User");
} catch (ClassNotFoundException e) {e.printStackTrace();
}
  • 4.object.getClass()
    (适合有对象示例的情况下)
User user = new User();
Class clazz3 = user.getClass();

2. 为什么要用到反射?

反射的作用:

  • 1.在运行时判断任意一个对象所属的类。
  • 2.在运行时构造任意一个类的对象。
  • 3.在运行时判断任意一个类所具有的成员变量和方法。
  • 4.在运行时调用任意一个对象的方法。
  • 5.生成动态代理。

优点

  • 反射可以在运行时加载、探知、使用完全未知的类,只需要知道类的路径,通过这个路径可以拿到我需要的东西,与类本身无关,灵活性更高了,类之间的耦合性也低。

缺点

  • (1)我们可以获取到类的私有信息,破坏了类的封装,使类变得不安全。使用反射还会降低程序性能。
  • (2)反射涉及了动态类型的解析,所以 JVM 无法对这些代码进行优化.
  • (3)反射代码破坏了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化。
  • 所以说使用反射优点突出,缺点同样突出。

反射的应用场景:

  • 1.逆向代码 ,例如反编译
  • 2.与注解相结合的框架 例如Retrofit
  • 3.单纯的反射机制应用框架 例如EventBus
  • 4.动态生成类框架 例如Gson

3. 反射方法的介绍

3.1 获得Class对象:

//第一种方式 通过Class类的静态方法——forName()来实现
class1 = Class.forName("com.lvr.reflection.Person");
//第二种方式 通过类的class属性
class1 = Person.class;
//第三种方式 通过对象getClass方法
Person person = new Person();
Class<?> class1 = person.getClass();

3.2 获取class对象的属性、方法、构造函数:

1.获取class对象的成员变量:

Field[] allFields = class1.getDeclaredFields();//获取class对象的所
有属性
Field[] publicFields = class1.getFields();//获取class对象的public
属性
Field ageField = class1.getDeclaredField("age");//获取class指定属性
Field desField = class1.getField("des");//获取class指定的public属性

2.获取class对象的方法:

Method[] methods = class1.getDeclaredMethods();//获取class对象的所
有声明方法
Method[] allMethods = class1.getMethods();//获取class对象的所有pub
lic方法 包括父类的方法
Method method = class1.getMethod("info", String.class);//返回次Cl
ass对象对应类的、带指定形参列表的public方法
Method declaredMethod = class1.getDeclaredMethod("info", String.
class);//返回次Class对象对应类的、带指定形参列表的方法

3.获取class对象的构造函数:

Constructor<?>[] allConstructors = class1.getDeclaredConstructor
s();//获取class对象的所有声明构造函数
Constructor<?>[] publicConstructors = class1.getConstructors();/
/获取class对象public构造函数
Constructor<?> constructor = class1.getDeclaredConstructor(Strin
g.class);//获取指定声明构造函数
Constructor publicConstructor = class1.getConstructor(String.cla
ss);//获取指定声明的public构造函数

4.其他方法:

Annotation[] annotations = (Annotation[]) class1.getAnnotations(
);//获取class对象的所有注解
Annotation annotation = (Annotation) class1.getAnnotation(Deprec
ated.class);//获取class对象指定注解
Type genericSuperclass = class1.getGenericSuperclass();//获取clas
s对象的直接超类的 Type
Type[] interfaceTypes = class1.getGenericInterfaces();//获取class
对象的所有接口的type集合

3.3 获取class对象的信息

boolean isPrimitive = class1.isPrimitive();//判断是否是基础类型
boolean isArray = class1.isArray();//判断是否是集合类
boolean isAnnotation = class1.isAnnotation();//判断是否是注解类
boolean isInterface = class1.isInterface();//判断是否是接口类
boolean isEnum = class1.isEnum();//判断是否是枚举类
boolean isAnonymousClass = class1.isAnonymousClass();//判断是否是
匿名内部类
boolean isAnnotationPresent = class1.isAnnotationPresent(Depreca
ted.class);//判断是否被某个注解类修饰
String className = class1.getName();//获取class名字 包含包名路径
Package aPackage = class1.getPackage();//获取class的包信息
String simpleName = class1.getSimpleName();//获取class类名
int modifiers = class1.getModifiers();//获取class访问权限
Class<?>[] declaredClasses = class1.getDeclaredClasses();//内部类
Class<?> declaringClass = class1.getDeclaringClass();//外部类

3.4 Java反射生成并操作对象

生成类的实例对象:

  • 1.Class对象调用newInstance()方法生成(要求该Class对象有默认的构造器,执行newInstance()方法实际上是用默认构造器生成该类的实例)
  • 2.获得对应的Constructor对象,再通过该Constructor对象的newInstance()方法生成,类似的,现获取指定的Construct对象,再通过该Constructor对象的NewInstance()方法来创建实例
//第一种方式 Class对象调用newInstance()方法生成
Object obj = class1.newInstance();
//第二种方式 对象获得对应的Constructor对象,再通过该Constructor对象的ne
wInstance()方法生成
Constructor<?> constructor = class1.getDeclaredConstructor(Strin
g.class);//获取指定声明构造函数
obj = constructor.newInstance("hello");

调用类的方法:

  • 1.通过Class对象的getMethods()方法或者getMethod()方法获得指定方法,返回
    Method数组或对象。
  • 调用Method对象中的 Object invoke(Object obj, Object… args) 方法。第一个参数对应调用该方法的实例对象,第二个参数对应该方法的参数。
// 生成新的对象:用newInstance()方法
Object obj = class1.newInstance();
//首先需要获得与该方法对应的Method对象
Method method = class1.getDeclaredMethod("setAge", int.class);
//调用指定的函数并传递参数
method.invoke(obj, 28);

当使用Method的invoke()方法来调用所需方法时,java要求程序必须有该方法权限。如果的调用private方法需要:
setAccessible(voolean flag):将Method对象设为ture(意味着该Method在使用时会取消java语言的访问权限检查)

访问成员变量值:

  • 先通过Class对象的getFields()方法或者getField()方法获得指定方法,返回Field数
    组或对象。
  • getXXX(Object obj):获取obj对象的该成员变量的值。此处的XXX对应8种基本类型。如果该成员变量的类型是引用类型,则取消get后面的XXX。
  • setXXX(Object obj,XXX val):将obj对象的该成员变量设置成val值。
//生成新的对象:用newInstance()方法
Object obj = class1.newInstance();
//获取age成员变量
Field field = class1.getField("age");
//将obj对象的age的值设置为10
field.setInt(obj, 10);
//获取obj对象的age的值
field.getInt(obj);

4. 一个实例

(1)在运行时判断任意一个对象所属的类。

Class aClass = Class.forName("com.Dan.Consumer");
System.out.print("?"+aClass.isInstance(new Consumer()));
// public boolean isInstance(Object obj)
// 当该 Class 对象表示一个已声明的类时,若指定的 Object 参数是所表示类(或其任一子类)的一个实例,则此方法返回 true;否则返回 false。

(2)在运行时构造任意一个类的对象。

Class aClass1 = Class.forName("com.Dan.Consumer");
Object object = aClass1.newInstance();
// throws InstantiationException, IllegalAccessException

(3)在运行时判断任意一个类所具有的成员变量和方法。

Class aClass2 = Class.forName("com.Dan.Consumer");
Method[] methods = aClass2.getDeclaredMethods();
Field[] fields = aClass2.getDeclaredFields();

(4)在运行时调用任意一个对象的方法。

Class aClass3 = Class.forName("com.Dan.Consumer");
Method[] methods[]= aClass3.getDeclaredMethods();
Object object = aClass3.newInstance();
Object returnObject = methods.invoke(object,null);

简单的说就是程序运行时,如果需要外部传进来一个对象,然后在程序中运用这个对象,我们就可以通过配置文件中类的路径,得到这个对象的所有信息,从而加以应用。

Java的很多框架的底层都是用反射来实现的,比如Struts2,JDBC,SQLite

Java里实现反射的那个类是java.lang.reflect,主要有以下四个类:

  • java.lang.reflect.AccessibleObject: 是另外三个类的基类
  • java.lang.reflect.Constructor:描述类的构造器,可以用 Constructor 创建新的对象。
  • java.lang.reflect.Field:描述类的域(属性),可以使用 get() 和 set() 方法读取和修改 Field 对象关联的字段;
  • java.lang.reflect.Method:描述类的方法,可以使用 invoke() 方法调用与 Method 对象关联的方法

介绍一下class类的常用方法:

一个实例:

4.1 准备两个类

定义两个类,Person和Employee,其中Employee继承自Person,且各自都有一个private,protected,public修饰的域(属性),Employee还有private,public修饰的方法

public class Person {public String name; // 姓名 公有protected String age;   // 年龄 保护private String hobby;   // 爱好   私有public Person(String name, String age, String hobby) {this.name = name;this.age = age;this.hobby = hobby;}public String getHobby() {return hobby;}
}public class Employee extends Person {public static Integer totalNum = 0; // 员工数public int empNo;   // 员工编号 公有protected String position;  // 职位 保护private int salary; // 工资   私有public void sayHello() {System.out.println(String.format("Hello, 我是 %s, 今年 %s 岁, 爱好是%s, 我目前的工作是%s, 月入%s元\n", name, age, getHobby(), position, salary));}private void work() {System.out.println(String.format("My name is %s, 工作中勿扰.", name));}public Employee(String name, String age, String hobby, int empNo, String position, int salary) {super(name, age, hobby);this.empNo = empNo;this.position = position;this.salary = salary;Employee.totalNum++;}
}

4.2 反射获取class对象

反射获取 Class 对象的方法:

  • 使用 Class 类的 forName 静态方法;
  • 直接获取某一个对象的 class;
  • 调用某个对象的 getClass() 方法
public class ClassTest {public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {Class c1 = Class.forName("reflect.Employee");   // 第1种,forName 方式获取Class对象Class c2 = Employee.class;      // 第2种,直接通过类获取Class对象Employee employee = new Employee("小明", "18", "写代码", 1, "Java攻城狮", 100000);Class c3 = employee.getClass();    // 第3种,通过调用对象的getClass()方法获取Class对象if (c1 == c2 && c1 == c3) {     // 可以通过 == 比较Class对象是否为同一个对象System.out.println("c1、c2、c3 为同一个对象");System.out.println(c1);     // class reflect.Employee}}
}

4.3 反射创建实例

  • 使用Class对象的newInstance()方法来创建Class对象对应类的实例
  • 先通过Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建实例
public class NewInstanceTest {public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {Class c = Date.class;Date date1 = (Date) c.newInstance();    // 第1种方式:使用Class对象的newInstance()方法来创建Class对象对应类的实例System.out.println(date1);      // Wed Dec 19 22:57:16 CST 2018long timestamp =date1.getTime();Constructor constructor = c.getConstructor(long.class); Date date2 = (Date)constructor.newInstance(timestamp);  // 第2种方式:先通过Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建实例System.out.println(date2);  // Wed Dec 19 22:57:16 CST 2018}
}

4.4 获取类的全部信息

上面我们定义了两个类,现在有个需求:获取Employee的类名,构造器签名,所有的方法,所有的域(属性)和值

获取类信息的部分API:
String getName(): 获取这个Class的类名

Constructor[] getDeclaredConstructors() :返回这个类的所有构造器的对象数组,包含保护和私有的构造器;相近的方法 getConstructors() 则返回这个类的所有公有构造器的对象数组,不包含保护和私有的构造器

Method[] getDeclaredMethods() :返回这个类或接口的所有方法,包括保护和私有的方法,不包括超类的方法;相近的方法 getMethods() :则返回这个类及其超类的公有方法的对象数组,不含保护和私有的方法

Field[] getDeclaredFields() :返回这个类的所有域的对象数组,包括保护域和私有域,不包括超类的域;还有一个相近的API getFields() :返回这个类及其超类的公有域的对象数组,不含保护域和私有域

int getModifiers() :返回一个用于描述Field、Method和Constructor的修饰符的整形数值,该数值代表的含义可通过Modifier这个类分析

Modifier 类 :它提供了有关Field、Method和Constructor等的访问修饰符的信息,主要的方法有:toString(int modifiers)返回整形数值modifiers代表的修饰符的字符串;isAbstract是否被abstract修饰;isVolatile是否被volatile修饰;isPrivate是否为private;isProtected是否为protected;isPublic是否为public;isStatic是否为static修饰;

实例:

public class ReflectionTest {public static void main(String[] args) throws ClassNotFoundException {String name;if (args.length > 0) {name = args[0];} else {Scanner in = new Scanner(System.in);System.out.println("输入一个类名(e.g. java.util.Date):"); // reflect.Employeename = in.next();}try {Class cl = Class.forName(name);Class superCl = cl.getSuperclass();String modifiers = Modifier.toString(cl.getModifiers());if (modifiers.length() > 0) {System.out.print(modifiers + " ");}System.out.print("class " + name);if (superCl != null && superCl != Object.class) {System.out.print(" extends " + superCl.getName());}System.out.println("\n{");printConstructors(cl); // 打印构造方法System.out.println();printMethods(cl);   // 打印方法System.out.println();printFields(cl);    // 打印属性System.out.println("}");} catch (ClassNotFoundException e) {e.printStackTrace();}System.exit(0);}/*** 打印Class对象的所有构造方法*/public static void printConstructors(Class cl) {Constructor[] constructors = cl.getDeclaredConstructors();for (Constructor c : constructors) {String name = c.getName();System.out.print("  ");String modifiers = Modifier.toString(c.getModifiers());if (modifiers.length() > 0) {System.out.print(modifiers + " ");}System.out.print(name + "(");// 打印构造参数Class[] paramTypes = c.getParameterTypes();for (int i = 0; i < paramTypes.length; i++) {if (i > 0) {System.out.print(", ");}System.out.print(paramTypes[i].getName());}System.out.println(");");}}/*** 打印Class的所有方法*/public static void printMethods(Class cl) {Method[] methods = cl.getDeclaredMethods();//Method[] methods = cl.getMethods();for (Method m : methods) {Class retType = m.getReturnType();  // 返回类型System.out.print("  ");String modifiers = Modifier.toString(m.getModifiers());if (modifiers.length() > 0) {System.out.print(modifiers + " ");}System.out.print(retType.getName() + " " + m.getName() + "(");Class[] paramTypes = m.getParameterTypes();for (int i = 0; i < paramTypes.length; i++) {if (i > 0) {System.out.print(", ");}System.out.print(paramTypes[i].getName());}System.out.println(");");}}/*** 打印Class的所有属性*/public static void printFields(Class cl) {Field[] fields = cl.getDeclaredFields();for (Field f: fields) {Class type = f.getType();System.out.print("  ");String modifiers = Modifier.toString(f.getModifiers());if (modifiers.length()> 0) {System.out.print(modifiers + " ");}System.out.println(type.getName() + " " + f.getName() + ";");}}
}

运行程序,然后在控制台输入一个我们想分析的类的全名,譬如 reflect.Employee,可得到下面的输出

输入一个类名(e.g. java.util.Date):
reflect.Employee
public class reflect.Employee extends reflect.Person
{private reflect.Employee(java.lang.String, java.lang.String, java.lang.String);public reflect.Employee(java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, int);public static void main([Ljava.lang.String;);public void sayHello();private void work();public static java.lang.Integer totalNum;public int empNo;protected java.lang.String position;private int salary;
}

4.5 运行时查看对象数据域的实际内容

在运行时查看对象的数据域的实际值。这个场景就像我们通过IDEA调试程序,设置断点拦截到程序后,查看某个对象的属性的值。

运行时查看对象数据域实际内容的相关API:

Class<?> getComponentType() 返回数组类里组件类型的 Class,如果不是数组类则返回null

boolean isArray() 返回这个类是否为数组,同类型的API还有 isAnnotation、isAsciiDigit、isEnum、isInstance、isInterface、isLocalClass、isPrimitive 等

int Array.getLength(obj) 返回数组对象obj的长度

Object Array.get(obj, i) 获取数组对象下标为i的元素

boolean isPrimitive() 返回这个类是否为8种基本类型之一,即是否为boolean, byte, char, short, int, long, float, 和double 等原始类型

Field getField(String name) 获取指定名称的域对象

AccessibleObject.setAccessible(fields, true) 当访问 Field、Method 和 Constructor 的时候Java会执行访问检查,如果访问者没有权限将抛出SecurityException,譬如访问者是无法访问private修饰的域的。通过设置 setAccessible(true) 可以取消Java的执行访问检查,这样访问者就获得了指定 Field、Method 或 Constructor 访问权限

Class<?> Field.getType() 返回一个Class 对象,它标识了此 Field 对象所表示字段的声明类型

Object Field.get(Object obj) 获取obj对象上当前域对象表示的属性的实际值,获取到的是一个Object对象,实际使用中还需要转换成实际的类型,或者可以通过 getByte()、getChar、getInt() 等直接获取具体类型的值

void Field.set(Object obj, Object value) 设置obj对象上当前域表示的属性的实际值

实例:

public class ObjectAnalyzer {private ArrayList<Object> visited = new ArrayList<>();public String toString(Object obj) {if (obj == null) {return "null";}if (visited.contains(obj)) {    // 如果该对象已经处理过,则不再处理return "...";}visited.add(obj);Class cl = obj.getClass(); // 获取Class对象if (cl == String.class) {   // 如果是String类型则直接转为Stringreturn (String) obj;}if (cl.isArray()) {        // 如果是数组String r = cl.getComponentType() + "[]{\n";     // 数组的元素的类型for (int i = 0; i < Array.getLength(obj); i++) {if (i > 0) {   // 不是数组的第一个元素加逗号和换行,显示更加美观r += ",\n";}r += "\t";Object val = Array.get(obj, i);if (cl.getComponentType().isPrimitive()) { // Class为8种基本类型的时候为 true,直接输出r += val;} else {r += toString(val); // 不是8中基本类型时,说明是类,递归调用toString}}return r + "\n}";}// 既不是String,也不是数组时,输出该对象的类型和属性值String r = cl.getName();do {r += "[";Field[] fields = cl.getDeclaredFields();    // 获取该类自己定义的所有域,包括私有的,不包括父类的AccessibleObject.setAccessible(fields, true); // 访问私有的属性,需要打开这个设置,否则会报非法访问异常for (Field f : fields) {if (!Modifier.isStatic(f.getModifiers())) { // 通过 Modifier 可获取该域的修饰符,这里判断是否为 staticif (!r.endsWith("[")) {r += ",";}r += f.getName() + "=";     // 域名称try {Class t = f.getType();  // 域(属性)的类型Object val = f.get(obj);   // 获取obj对象上该域的实际值if (t.isPrimitive()) {     // 如果类型为8种基本类型,则直接输出r += val;} else {r += toString(val);     // 不是8种基本类型,递归调用toString}} catch (IllegalAccessException e) {e.printStackTrace();}}}r += "]";cl = cl.getSuperclass(); // 继续打印超类的类信息} while (cl != null);return r;}
}

测试:

public class ObjectAnalyzerTest {public static void main(String[] args) {int size = 4;ArrayList<Integer> squares = new ArrayList<>(size);for (int i = 0; i < size; i++) {squares.add(i * i);}ObjectAnalyzer objectAnalyzer = new ObjectAnalyzer(); // 创建一个上面定义的分析类ObjectAnalyzer的对象System.out.println(objectAnalyzer.toString(squares)); // 分析ArrayList<Integer>对象的实际值Employee employee = new Employee("小明", "18", "爱好写代码", 1, "Java攻城狮", 100); // 分析自定义类Employee的对象的实际值System.out.println(objectAnalyzer.toString(employee));}
}

结果:

java.util.ArrayList[elementData=class java.lang.Object[]{java.lang.Integer[value=0][][],java.lang.Integer[value=1][][],java.lang.Integer[value=4][][],java.lang.Integer[value=9][][]
},size=4][modCount=4][][]
reflect.Employee[empNo=1,position=Java攻城狮,salary=100][name=小明,age=18,hobby=爱好写代码][]

其中ArrayList打印了类名和5个元素的类型和值,Employee 打印了类名,自己定义的3个基本类型的属性的实际值,和父类Person的3个基本类型的属性的实际值

需要注意的是,position,age 是 protected 保护域,salary,hobby 是 private 私有域,Java的安全机制只允许查看任意对象有哪些域,但是不允许读取它们的值

通过 AccessibleObject.setAccessible(fields, true) 将域设置为了可访问,取消了Java的执行访问检查,因此可以访问,如果不加会报异常 IllegalAccessException

我们通过 setAccessible(true) 绕过了Java执行访问检查,因此能够访问私有域,通过 Field.getType() 获得了属性的声明类型,通过了 Field.get(Object obj) 获得了该域属性的实际值,还有一个没用上的 Field.set(Object obj, Object value) 设置域属性的实际值

4.6 调用任意方法

上面我们已经获取了类的构造器,方法,域,查看和设置了域的实际值,那么是不是还可以在调用对象的方法呢?

调用任意方法相关的API:

Method getMethod(String name, Class<?>… parameterTypes) 获取指定的 Method,参数 name 为要获取的方法名,parameterTypes 为指定方法的参数的 Class,由于可能存在多个同名的重载方法,所以只有提供正确的 parameterTypes 才能准确的获取到指定的 Method

Object invoke(Object obj, Object… args) 执行方法,第一个参数执行该方法的对象,如果是static修饰的类方法,则传null即可;后面是传给该方法执行的具体的参数值

实例:

public class MethodTableTest {public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {Employee employee = new Employee("小明", "18", "写代码", 1, "Java攻城狮", 100000);Method sayHello = employee.getClass().getMethod("sayHello");System.out.println(sayHello);   // 打印 sayHello 的方法信息sayHello.invoke(employee);      // 让 employee 执行 sayHello 方法double x = 3.0;Method square = MethodTableTest.class.getMethod("square", double.class);  // 获取 MethodTableTest 的square方法double y1 = (double) square.invoke(null, x);    // 调用类方法 square 求平方,方法参数 x System.out.printf("square    %-10.4f -> %10.4f%n", x, y1);Method sqrt = Math.class.getMethod("sqrt", double.class);   // 获取 Math 的 sqrt 方法double y2 = (double) sqrt.invoke(null, x);  // 调用类方法 sqrt 求根,方法参数 x System.out.printf("sqrt      %-10.4f -> %10.4f%n", x, y2);}// static静态方法 计算乘方public static double square(double x) {return x * x;}
}

结果:

public void reflect.Employee.sayHello()
Hello, 我是 小明, 今年 18 岁, 爱好是写代码, 我目前的工作是Java攻城狮, 月入100000元square    3.0000     ->     9.0000
sqrt      3.0000     ->     1.7321

Java——反射机制相关推荐

  1. 利用java反射机制 读取配置文件 实现动态类载入以及动态类型转换

    作者:54dabang 在spring的学习过程之中,我们能够看出通过配置文件来动态管理bean对象的优点(松耦合 能够让零散部分组成一个总体,而这些总体并不在意之间彼此的细节,从而达到了真正的物理上 ...

  2. Struts2中action接收参数的三种方法及ModelDriven跟Preparable接口结合JAVA反射机制的灵活用法...

    Struts2中action接收参数的三种方法及ModelDriven跟Preparable接口结合JAVA反射机制的灵活用法 www.MyException.Cn   发布于:2012-09-15 ...

  3. Java反射机制分析指南

    一.JAVA是动态语言吗? 一般而言,说到动态言,都是指在程序运行时允许改变程序结构或者变量类型,从这个观点看,JAVA和C++一样,都不是动态语言. 但JAVA它却有着一个非常突出的动态相关机制:反 ...

  4. 反射 字段_详解面试中常考的 Java 反射机制

    反射(Reflection) 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说"自审",并能直接操作程序的内部属性和方法. 反射是一项高级 ...

  5. 【java】java反射机制,动态获取对象的属性和对应的参数值,并属性按照字典序排序,Field.setAccessible()方法的说明【可用于微信支付 签名生成】...

    方法1:通过get()方法获取属性值 package com.sxd.test.controller;public class FirstCa{private Integer num;private ...

  6. java基础-java反射机制

    2019独角兽企业重金招聘Python工程师标准>>> 引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓"登高必自卑,涉远必自迩" ...

  7. 利用java反射机制进行对象操作

    我们经常使用COMMONS-BEANUTILS包来进行bean的操作,例如从map到bean获从bean到map的映射,那么实现的原理是什么呢,下面举个简单的操作的例子:首先,我建立一个bean pu ...

  8. java反射机制知识_Java反射机制讲解,程序员必须掌握的知识点

    关注程序员7歌,一起用技术改变世界 大家好,我是程序员7歌,今天我为大家讲解Java的反射机制. 首先我们来看看反射的概念: Java反射说的就是在程序运行中,任何一个类,我们都可以知道这个类的方法和 ...

  9. java继承 映射_hibernate继承关系映射和java反射机制的运用

    转:http://blog.csdn.net/derpvailzhangfan/article/details/1957946 ,感谢博主分享 Notes:hibernate元数据的运用:uuid的概 ...

  10. java初反射_初始 java 反射机制 (一)

    反射机制详解 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为j ...

最新文章

  1. 搭建Cacti监控系统(一)-- 搭建LNMP 环境
  2. 里程碑!SpaceX 载人首飞发射成功,马斯克填补美国载人飞行近十年空白
  3. C++的那些事:你真的了解引用吗
  4. pythonexcel工具介绍_Python处理excel的强大工具
  5. 微软宣布已获批:重新向华为出口软件!
  6. 实验5 振幅调制(集成乘法器幅度调制电路)
  7. 大学计算机网络实验网线制作,计算机网络实验报告 网线的制作.doc
  8. 谢霆锋断言暂不再婚 赞张柏芝教子有方
  9. 邮箱服务器 拦截策略,企业邮箱服务器的安全管理策略
  10. Python标准库:内置函数complex([real[, imag]])
  11. 印刷常用专业术语解释
  12. opencv双目相机标定-示例代码分析
  13. Ardunio 完成STM32板子的串口通信
  14. 微信小程序开发与mysql_微信小程序云开发之云数据库入门
  15. 深圳湾去香港办招行香港一卡通流程(前篇)
  16. 【转载】实时嵌入式软件开发的25个常见错误
  17. android设置为默认短信应用,如何在Android上设置默认短信应用 | MOS86
  18. MATLAB运动车辆检测系统
  19. php 原理 淘口令 解密_淘口令解析 - VX_super19911115 - 博客园
  20. 前端svg字体图标使用_材质设计图标字体与svg以及如何在角度中使用svg精灵

热门文章

  1. 可以实现内网穿透的几款工具
  2. 你知道Java程序猿工资有多少吗?
  3. Java行业薪资待遇一般都多少钱?
  4. java string转short_java类型转换
  5. ios文件连接 百度网盘服务器,iOS系统教程:iphone怎么解压百度网盘文件
  6. 【读书笔记】商业自传-耐克科技,鞋狗:耐克创始人菲尔.奈特亲笔自传_2020.06.01
  7. CSS样式层叠关系(一)-- 外部,内部与内联
  8. 用Arduino改装小米沙漠赛车
  9. 四六级热点词汇总结疫情、文化、社会热点、脱贫等
  10. 面试官谈游戏开发入行--选择