- 1 Class 对象的三种获取方式
package demo1;
public class Test1 {
public static void main(String[] args) throws Exception {
//演示对象
Person p = new Person();
//获得Class对象的三种方式
//1 对象.getClass方法获得
Class c1 = p.getClass();
//2 类名.Class 静态属性 获得
Class c2 = Person.class;
//3 Class.forName()方法获得
Class c3 = Class.forName("demo1.Person");
System.out.println("c1:"+c1);
System.out.println("c2:"+c2);
System.out.println("c3:"+c3);
}
}
- 2 通过反射获取构造方法并使用
package demo1;
import java.lang.reflect.Constructor;
public class Test2 {
/*
*
* 通过反射获取构造方法并使用
*
*/
public static void main(String[] args) throws Exception {
//----------获得Class对象----------
Class c = Class.forName("demo1.Person");
//----------获得所有构造方法----------
Constructor[] cons = c.getConstructors();
for(Constructor con : cons) {
System.out.println(con);
}
/*
* 输出
* public demo1.Person()
* public demo1.Person(java.lang.String,java.lang.String,int,java.lang.String)
*/
//----------获得共有构造方法----------
//获得空参构造方法
Constructor con = c.getConstructor();
System.out.println(con);
//输出 public demo1.Person()
//获得指定参数构造方法
//public Constructor<T> getConstructor(Class<?>... parameterTypes) 注意参数室Class对象
con = c.getConstructor(String.class, String.class, int.class , String.class);
System.out.println(con);
//输出 public demo1.Person(java.lang.String,java.lang.String,int,java.lang.String)
//----------获得私有构造方法----------
//获得空参私有构造方法
cons = c.getDeclaredConstructors();
for (Constructor con1 : cons) {
System.out.println(con1);
}
//输出 private demo1.Person(java.lang.String)
//获得指定参数构造方法
con = c.getDeclaredConstructor(String.class);
System.out.println(con);
//输出 private demo1.Person(java.lang.String)
}
}
- 3 通过反射方式,获取构造方法,创建对象
package demo1;
import java.lang.reflect.Constructor;
public class Test3 {
/*
* 通过反射方式,获取构造方法,创建对象
* 获取构造方法,步骤如下:
1. 获取到Class对象
2. 获取指定的构造方法
3. 通过构造方法类Constructor中的方法,创建对象
*/
public static void main(String[] args) throws Exception {
//1. 获取到Class对象
Class c = Class.forName("demo1.Person");
//2. 获取指定的构造方法
Constructor<Person> con = c.getConstructor(String.class, String.class, int.class, String.class);
//3. 通过构造方法类Constructor中的方法,创建对象
//public T newInstance(Object... initargs)
//如果Constructor没有写泛形的话,这里应该用Object来接收实例
Person p = con.newInstance("alex", "男", 33, "coder");
System.out.println(p);
//输出 Person [name=alex, sex=男, age=33, title=coder]
}
}
- 4 通过反射方式,获取私有构造方法,创建对象
package demo1;
import java.lang.reflect.Constructor;
public class Test4 {
/*
* 通过反射方式,获取私有构造方法,创建对象
* AccessibleObject 类是 Field、Method 和 Constructor 对象的父类。它提供了将反射的对象标记为在使用时取消默认 Java 语言访问控制检查的能力。
对于公共成员、默认(打包)访问成员、受保护成员和私有成员,在分别使用 Field、Method 或 Constructor 对象来设置或获取字段、调用方法,或者创建和初始化类的新实例的时候,会执行访问检查。常用方法如下:
public void setAccessible(boolean flag) throws SecurityException
参数值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。参数值为 false 则指示反射的对象应该实施 Java 语言访问检查。
获取私有构造方法,步骤如下:
1. 获取到Class对象
2. 获取指定的构造方法
3. 暴力访问, 通过setAccessible(boolean flag)方法
4. 通过构造方法类Constructor中的方法,创建对象
public T newInstance(Object... initargs)
*/
public static void main(String[] args) throws Exception {
//1. 获取到Class对象
Class c = Class.forName("demo1.Person");
//2. 获取指定的构造方法
Constructor<Person> con = c.getDeclaredConstructor(String.class);
System.out.println(con);
//得到私有构造器 private demo1.Person(java.lang.String)
//3.暴力访问, 通过setAccessible(boolean flag)方法
con.setAccessible(true);
//4. 通过构造方法类Constructor中的方法,创建对象
//public T newInstance(Object... initargs)
//如果Constructor没有写泛形的话,这里应该用Object来接收实例
Person p = con.newInstance("alex");
System.out.println(p);
//输出 Person [name=alex, sex=null, age=0, title=null]
}
}
- 5 通过反射获取成员变量并使用
package demo1;
import java.lang.reflect.Field;
public class Test5 {
/*
* 通过反射获取成员变量并使用
* 在反射机制中,把类中的成员变量使用类Field表示。可通过Class类中提供的方法获取成员变量:
返回一个成员变量
public Field getField(String name) 获取指定的 public修饰的变量
public Field getDeclaredField(String name) 获取指定的任意变量
返回多个成员变量
public Field[] getFields() 获取所有public 修饰的变量
public Field[] getDeclaredFields() 获取所有的 变量 (包含私有)
*/
public static void main(String[] args) throws Exception {
Class c = Class.forName("demo1.Person");
//--------获得所有共有的成员变量--------
Field[] fields = c.getFields();
for (Field field : fields) {
System.out.println(field);
}
//输出 public java.lang.String demo1.Person.title
//--------获得特定共有的成员变量--------
Field titleField = c.getField("title");
System.out.println(titleField);
//输出 public java.lang.String demo1.Person.title
//--------获得所有私有的成员变量--------
Field[] fields1 = c.getDeclaredFields();
for (Field field : fields1) {
System.out.println(field);
}
/*
* getDeclaredFields()方法会获得所有的成员变量
*
* private java.lang.String demo1.Person.name
private java.lang.String demo1.Person.sex
private int demo1.Person.age
public java.lang.String demo1.Person.title
*
*/
//--------获得特定私有的成员变量--------
Field nameField = c.getDeclaredField("name");
Field sexField = c.getDeclaredField("sex");
Field ageField = c.getDeclaredField("age");
//用getDeclaredField获得共有成员变量也是可行的
Field titleField1 = c.getDeclaredField("title");
System.out.println(nameField);
System.out.println(sexField);
System.out.println(ageField);
System.out.println(titleField1);
/*
* 输出
* private java.lang.String demo1.Person.name
private java.lang.String demo1.Person.sex
private int demo1.Person.age
public java.lang.String demo1.Person.title
*/
}
}
- 6 通过反射,创建对象,获取指定的成员变量,进行赋值与获取值操作
package demo1;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class Test6 {
/*
* 通过反射,创建对象,获取指定的成员变量,进行赋值与获取值操作
* 获取成员变量,步骤如下:
1. 获取Class对象
2. 获取构造方法
3. 通过构造方法,创建对象
4. 获取指定的成员变量(私有成员变量,通过setAccessible(boolean flag)方法暴力访问)
5. 通过方法,给指定对象的指定成员变量赋值或者获取值
public void set(Object obj, Object value)
在指定对象obj中,将此 Field 对象表示的成员变量设置为指定的新值
public Object get(Object obj)
返回指定对象obj中,此 Field 对象表示的成员变量的值
*/
public static void main(String[] args) throws Exception {
//1. 获取Class对象
Class c = Class.forName("demo1.Person");
//2. 获取构造方法
Constructor<Person> con = c.getConstructor(String.class, String.class, int.class, String.class);
//3. 通过构造方法,创建对象
Object obj = con.newInstance("alex", "男", 33, "coder");
//4. 获取指定的成员变量(私有成员变量,通过setAccessible(boolean flag)方法暴力访问)
Field nameField = c.getDeclaredField("name");
nameField.setAccessible(true);
//5. 通过方法,给指定对象的指定成员变量赋值或者获取值
nameField.set(obj, "alex1");
System.out.println(obj);
// 输出 Person [name=alex1, sex=男, age=33, title=coder]
//获得成员变量值
System.out.println("成员变量name="+nameField.get(obj));
}
}
- 7 通过反射获取成员方法并使用
package demo1;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class Test7 {
/*
* 通过反射获取成员方法并使用
*
* 在反射机制中,把类中的成员方法使用类Method表示。可通过Class类中提供的方法获取成员方法:
返回获取一个方法:
public Method getMethod(String name, Class<?>... parameterTypes)
获取public 修饰的方法
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
获取任意的方法,包含私有的
参数1: name 要查找的方法名称; 参数2: parameterTypes 该方法的参数类型
返回获取多个方法:
public Method[] getMethods() 获取本类与父类中所有public 修饰的方法
public Method[] getDeclaredMethods() 获取本类中所有的方法(包含私有的)
*/
public static void main(String[] args) throws Exception {
//
Class c = Class.forName("demo1.Person");
Constructor<Person> con = c.getConstructor();
Person obj = con.newInstance();
obj.setName("alex");
// //获得共有方法
// Method[] methods = c.getMethods();
// for (Method method : methods) {
// System.out.println(method);
// }
// System.out.println("----------------------");
// //获得所有方法
// methods = c.getDeclaredMethods();
// for (Method method : methods) {
// System.out.println(method);
// }
//获得指定方法
Method method = c.getDeclaredMethod("sleep", int.class);
//设置setAccessible
method.setAccessible(true);
//调用该函数
method.invoke(obj, 10);
method = c.getDeclaredMethod("eat");
method.setAccessible(true);
method.invoke(obj);
}
}
- 8 反射配置文件
package demo1;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Properties;
import java.util.Set;
public class Test8 {
/*
* 反射配置文件
*
* 通过反射配置文件,运行配置文件中指定类的对应方法
读取Peoperties.txt文件中的数据,通过反射技术,来完成Person对象的创建
*/
public static void main(String[] args) throws Exception {
//获得配置文件中的类与方法
Properties pro = new Properties();
pro.load(new InputStreamReader(
Test8.class.getClassLoader().getResourceAsStream("config.properties")));
Set<String> set = pro.stringPropertyNames();
for (String key : set) {
System.out.println(key+ "=" +pro.getProperty(key));
}
String className = pro.getProperty("className");
String method = pro.getProperty("method");
//获得Class对象
Class c = Class.forName(className);
//获得构造器
Constructor con = c.getDeclaredConstructor();
//获得Object对象
Object obj = con.newInstance();
//获得指定方法
Method newMethod = c.getDeclaredMethod(method);
//取消类型检查
newMethod.setAccessible(true);
//执行方法
newMethod.invoke(obj);
}
}
- 9 泛形擦除
package demo1;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class Test9 {
/*
* 泛型擦除
* 将已存在的ArrayList<Integer>集合中添加一个字符串数据,如何实现?
其实程序编译后产生的.class文件中是没有泛型约束的,这种现象我们称为泛型的擦除。
那么,我们可以通过反射技术,来完成向有泛型约束的集合中,添加任意类型的元素
*
*/
public static void main(String[] args) throws Exception, SecurityException {
ArrayList<String> list = new ArrayList<>();
Class c = list.getClass();
list.add("asdf");
Method m = c.getMethod("add", Object.class);
m.invoke(list, new Integer(124));
System.out.println(list);
}
}
- Person 类
package demo1;
public class Person {
private String name;
private String sex;
private int age;
public String title;
public Person() {}
public Person(String name, String sex, int age, String title) {
this.name = name;
this.sex = sex;
this.age = age;
this.title = title;
}
private Person(String name) {
this.name = name;
}
private void eat() {
System.out.println(name+"在吃饭...");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@Override
public String toString() {
return "Person [name=" + name + ", sex=" + sex + ", age=" + age + ", title=" + title + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((sex == null) ? 0 : sex.hashCode());
result = prime * result + ((title == null) ? 0 : title.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (sex == null) {
if (other.sex != null)
return false;
} else if (!sex.equals(other.sex))
return false;
if (title == null) {
if (other.title != null)
return false;
} else if (!title.equals(other.title))
return false;
return true;
}
}