Here I will provide code to illustrate
Previous forward operation: instantiate an object: By constructing the method object instance of the class.
Reflection: to obtain information sources depending on the object, the object's class gets created by instantiating objects.
Class object class obtained three methods:
(1) a method in class java.lang.Object: getClass () method, all the java object can call the method, returns the Class object corresponding to the object's class.
(2) the class name .class attribute of a class call the class to get the Class object corresponding to the class. Example: Student.class returns Student Class object corresponding to a class.
(3) the use of the Class class forName (String className) static method. public static Class <?> forName ( String className) throws ClassNotFoundException.
Note: the same class loader, Class object is a class of only one.
public static void main(String[] args) {
Date date=new Date();// 创建对象
//class 关键字 Class 类型
Class class1=date.getClass(); //1.getClass()方法
System.out.println(class1);
System.out.println(date instanceof Date); //若date是Date类,返回true,否则返回false
Class class2=Date.class; //2.通过属性来获取对象.类名.class
System.out.println(class2);
//通过Class.forName 类的全限定名
try{
Class class3=Class.forName("java.util.Date"); //3.forName()
System.out.println(class3);
System.out.println("=====>");
//当前三个Class对象都是描述iava.util.Date
System.out.println(class1==class2);
System.out.println(class2==class3);
}catch(ClassNotFoundException e){
e.printStackTrace();
}
}
Three objects are described in the same
operation results
factory mode:
Traditional factory mode: one for each additional ⼀ Connector class will need to modify the submenus ⼯ class factory shipping, contrary to the principles of OCP
by the reflection process, the problem can be solved
before , we need to understand the knowledge:
(1) class constructor can instantiate an object
(2) by reflection to create an instance of the class object
. newInstance class obtained by the object class () method to instantiate a object (class constructor with no arguments)
B class object class constructor constructor object acquired through the newInstance constructor of (...) instantiate the object.
realize the plant:
interface Clothes{
void wear();
}
class Shirt implements Clothes{
@Override
public void wear() {
System.out.println("穿衬衫");
}
}
class Skirt implements Clothes{
@Override
public void wear() {
System.out.println("穿短袖");
}
}
class Pants implements Clothes{
@Override
public void wear() {
System.out.println("穿牛仔裤");
}
}
class ClothesFactory{
private ClothesFactory(){
}
public static Clothes getClothesInstance(String className){ //工厂返回的是接口类型
//new->具体类型耦合
try{
Class class1=Class.forName(className);
return (Clothes)class1.newInstance(); //获取实例化对象
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
throw new RuntimeException("Factory生产不了"+className);
}
}
public class Factory {
public static void main(String[] args) {
Clothes clothes=ClothesFactory.getClothesInstance("com.zh.reflect.Skirt");
clothes.wear();
}
}
After reflection cited START, whenever new class Connector Submenu, No need for modifications to the class code ⼯ The factory will be very ⽅ into submenus ⾏ Connector class expansion.
And the reflection type operation:
1. Get the parent class information
getPackage () getName (): acquire the package name.
GetSuperclass () getName (); to obtain the fully qualified name of the class name of the class package name..
GetSimpleName (): acquire only the name of the class
getInterfaces (): get the interface
code to achieve:
public static void main(String[] args) {
Class class1 = Test1.class; //类名.class
System.out.println("包名:" + class1.getPackage().getName());
System.out.println("父类:" + class1.getSuperclass().getName());//类的全限定名 包名.类名
System.out.println("父类:" + class1.getSuperclass().getSimpleName());//只是类名
System.out.println("========>");
System.out.println("接口: ");
Class[] interfaces = class1.getInterfaces();
for (Class cls : interfaces) {
System.out.println(cls.getName());
System.out.println(cls.getSimpleName());
}
}
Class interface and implementation of the interface and construction methods:
interface Clothes1{}
interface Message1{}
class Test1 implements Clothes1, Message1{
public Test1(Integer a, Integer b) { }
public Test1(Integer a, String b) { }
public Test1(Integer a) { }
public Test1() { }
}
Results:
2.Class class when reflected by the object instance of the class, only the configuration parameters can be adjusted ⽆ Use class. If the current class is not the configuration parameters ⽆ unusable tone Use Class class, it can only be transferred through explicit configuration Use instantiation process.
By the newInstance Constructor (...) of the object instance
embodied as follows:
code implementation:
public static void main(String[] args) {
//获取所有的构造方法
Class class1 = Test1.class; //类名.class
Constructor[] constructors=class1.getConstructors();
System.out.println("获取所有的构造方法");
for(Constructor c:constructors){
Class[] parameterCls=c.getParameterTypes();
String parameter= Arrays.toString(parameterCls);
System.out.println(c.getName()+"(" + parameter + ")");
}
System.out.println("获取指定的构造方法");
try{
Constructor constructor=class1.getConstructor(Integer.class,String.class);
System.out.println(constructor);
//通过Constructor实例化对象
//new Test(...)
Object object=constructor.newInstance(20,"zhanghao"); //实例化对象
System.out.println(object.getClass());
}
catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
运行结果:
3.反射调用普通方法:
getMethods():获取包括父类的所有方法
getDeclaredMethods():获取自己的所有方法
获取指定的方法:
步骤:
(1)用newInstance获取对象
(2)获取对象的方法,并且调用
Method method = class1.getMethod(“setName”, String.class);
Object returnVal = method.invoke(person, “zhanghao”);
此时返回的值是null,只是修改了,并没有传入值
(3)获取对象的方法,并且调用
Method getNameMethod = class1.getMethod(“getName”);
Object returnName = getNameMethod.invoke(person);
此时取值了,返回输入的值。
具体代码实现:
(1)父类和子类的属性,构造方法,普通方法实现
class Person {
private int age;
public String name;
public Person() {
}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
class Student extends Person {
private String school;
private String skill;
private LocalDateTime birthday;
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
public String getSkill() {
return skill;
}
public void setSkill(String skill) {
this.skill = skill;
}
public LocalDateTime getBirthday() {
return birthday;
}
public void setBirthday(LocalDateTime birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "Student{" +
"school='" + school + '\'' +
", skill='" + skill + '\'' +
", birthday=" + birthday +
"} " + super.toString();
}
(2)获取方法的具体实现:
public static void main1(String[] args) {
Class class1 = Person.class;
System.out.println("获取包括父类的所有的方法:");
Method[] methods = class1.getMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("=======>");
System.out.println("获取自己的所有的方法: ");
Method[] methods1 = class1.getDeclaredMethods();
for (Method method : methods1) {
System.out.println(method);
}
System.out.println("======>");
System.out.println("获取指定的方法: ");
try {
Person person = (Person) class1.newInstance(); //1.获取对象
System.out.println("before Person :" + person);
System.out.println("=======>");
//2.获取对象的方法,并且调用(修改)
Method method = class1.getMethod("setName", String.class);
Object returnVal = method.invoke(person, "zhanghao");
System.out.println(returnVal);//null
System.out.println("after Person: " + person);
System.out.println("====>");
//3.获取对象的方法,并且调用(取值)
Method getNameMethod = class1.getMethod("getName");
Object returnName = getNameMethod.invoke(person);
System.out.println(returnName);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
Run Results:
(4) the reflective properties of call
subclass inherits all the parent class structures, depending on whether the access modifiers can access
all the properties of a given class will ⼀ space partitioned into ⾏ after the class object is instantiated, so in this case If you want to tune Using the class attribute, it must ensure that there is instantiated object.
1.getFields (): Returns the public properties of the parent class and subclass
2.getDeclaredFields (): Returns the subclass all the attributes
3.public Method getDeclaredMethod (<?> String nameClass ... parameterTypes): Gets the class name of the specified property, specified properties obtained following code embodied see
public static void main(String[] args) {
Class class1=Student.class;
System.out.println("获取属性");
System.out.println("1.====>");
System.out.println("父类和子类的公开属性: ");
Field[] fileds=class1.getFields() ;//返回父类和子类的公开属性
for(Field field:fileds){
System.out.println(field.getType() + " " + field.getName());
System.out.println(field);
}
System.out.println("2====>");
System.out.println("子类的所有属性");
Field[] fields1=class1.getDeclaredFields() ;//返回子类的所有属性
for(Field field:fields1){
System.out.println(field.getType() + " " + field.getName());
System.out.println(field);
}
System.out.println("=====>");
System.out.println("获取指定属性");
try {
Field skillField = class1.getDeclaredField("skill");
System.out.println(skillField);
//使用属性
Student student = new Student();
student.setSkill("yuwen,shuxue,english");
student.getSkill();
//true表示可以访问私有的属性
skillField.setAccessible(true);
//get 获取
Object skillValue = skillField.get(student);
System.out.println(skillValue);
//set 修改
skillField.set(student, "pysh"); //修改
System.out.println(student);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
operation result: