**```java
/*
-
反射机制
-
认识反射
-
理解反射的作用
-
利用反射来调用类的结构
-
1 在正常情况下,一定是先有类而后再产生对象
-
所谓的反就是指可以利用对象找到对象的出处,在Object类里面提供有一个人方法
-
取得class对象
-
public final 类> getClass()
-
Class 类对象实例化
-
java.lang.Class 是一个类,这个类是反射操作的源头,所有的反射都是要从此类开始
-
执行,
-
三种实例化方式
-
1 调用getCalss
-
2 使用类.class 取得
-
3 调用Class类提供的一个方法
-
实例化class对象
-
public static 类> forName(String className)
throws ClassNotFoundException -
反射实例化对象
-
当拿到一个类的时候,肯定要直接使用关键字new进行对象的实例化操作,
-
有class类对象,那么就可以利用反射实现对象实例化对象
-
实例化对象方法:public T newInstance() throws InstantiationException,IllegalAccessException
-
有了反射之后,以后进行对象实例化的操作不再只是单独的依靠关键字new完成了
-
反射也同样可以完成并不表示new就被完全取代了。
-
在任何的开发之中, new是造成耦合的最大元凶,一切的耦合是new
-
此时的程序就真正完成了了解耦合的目的,而且可拓展性非常的强
-
使用反射调用构造
-
Exception in thread “main” java.lang.InstantiationException: leiku.BookQ
at java.base/java.lang.Class.newInstance(Class.java:639)
at leiku.fangshejizhi.main(fangshejizhi.java:96)
Caused by: java.lang.NoSuchMethodException: leiku.BookQ.()
at java.base/java.lang.Class.getConstructor0(Class.java:3508)
at java.base/java.lang.Class.newInstance(Class.java:626)
… 1 more -
以上所出现的错误指的就是因为当前Book类里面没有无参构造方法,所以程序无法
-
进行对象的实例化,只能够明确调用有参构造方法
-
在Class类提供有一个方法取得构造
-
public Constructor>[] getConstructors() throws SecurityException
-
取得全部构造
-
public Constructor getConstructor(类>… parameterTypes) throws NoSuchMethodException,
-
SecurityException 取得一个指定参数顺序的构造
-
以上两个方法返回的都是java.lang.reflect.Constructor类的对象
-
在这个类中提供有一个明确传递有参构造内容的实例化对象方法
-
public T newInstance(Object… initargs)
throws InstantiationException,
IllegalAccessException,
IllegalArgumentException,
InvocationTargetException -
接单java类的开发之中不管提供有多少个构造方法,请至少保留无参构造
-
反射调用方法
-
类中的普通方法只有在一个类产生实例化对象之后才可以调用,并且实例化的方式有三种
-
在Class类里面提供有以下取得类中Method的操作:
-
public Method[] getMethods() throws SecurityException 取得类中的全部方法
-
public Method getMethod(String name,
类>… parameterTypes)
throws NoSuchMethodException,
SecurityException 取得指定方法
以上返回的是Method类的对象
调用方法
public Object invoke(Object obj,
Object… args)
throws IllegalAccessException,
IllegalArgumentException,
InvocationTargetException反射调用成员
类中的属性一定要在奔雷实例化对象产生之后才可以分配内存空间。在class类里面
提供有取得成员的方法:
取得全部成员:public Field[] getDeclaredFields() throws SecurityException
取得指定成员:public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException -
在Field 类中有两个重要的方法
-
取得属性内容 :public Object get(Object obj)
throws IllegalArgumentException,
IllegalAccessException
设置属性内容:public void set(Object obj,Object value)
throws IllegalArgumentException,
IllegalAccessExceptionjava.lang.reflect.AccessibleObject类下面:
有Executable:下面继续继承了Constructor Methed
Field
public void setAccessible(boolean flag) throws SecurityException
设置是否封装构造方法和普通方法同样可以取消封装,只不过很少这样去做,而且对于属性的访问还是建议
使用setter,getter方法完成。
```java
package leiku;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.Date;
interface Fruit
{
public void eat();
}
class Apple implements Fruit
{
public void eat()
{
System.out.println("APPLE");
}
}
class Orange implements Fruit
{
public void eat()
{
System.out.println("orange");
}
}
class Factory
{
public static Fruit getInstance(String className)
{
Fruit f=null;
try {
f=(Fruit)Class.forName(className).newInstance();
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return f;
}
}
public class fangshejizhi {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
// Date date = new Date();
// System.out.println(date);
// Class> cls = date.getClass();
// Class> cls = Date.class;
// Class> cls = Class.forName("java.util.Date");
// System.out.println(cls);///class java.util.Date
// BookQ b = new BookQ();
// System.out.println(b);
Class> cls = Class.forName("leiku.BookQ");
// Object obj = cls.newInstance(); /// 使用new调用无参构造
// BookQ book = (BookQ) obj;
// System.out.println(obj);
///反射调用构造
// Constructor> con = cls.getConstructor(String.class,double.class); String类型 和double类型
// Object obj = con.newInstance("java开发",79.8); /// 实例化对象
// System.out.println(obj);
// Fruit f = Factory.getInstance("leiku.Orange");
// f.eat();
//反射调用方法
// String fieldName = "title"; /// 要操作的成员
// Object obj = cls.newInstance(); // 必须给实例化
// Method setMet = cls.getMethod("set"+initcap(fieldName), String.class);
// Method getMet = cls.getMethod("get"+initcap(fieldName));
// setMet.invoke(obj, "java开发");
// System.out.println(getMet.invoke(obj));
// System.out.println(initcap(fieldName));
// 反射调用属性
Object obj = cls.newInstance();
Field titleField = cls.getDeclaredField("title");
titleField.setAccessible(true); /// 封装取消了
titleField.set(obj, "java开发"); /// 相当于Book类对象.title =java开发
System.out.println(titleField.get(obj));
//
}
public static String initcap(String str)
{
return str.substring(0,1).toUpperCase()+str.substring(1)
; }
}
package leiku;
public class BookQ {
// public BookQ() {
// // TODO Auto-generated constructor stub
// System.out.println("dasda");
// }
// public BookQ()
// {
//
// }
private String title;
private double price;
// public BookQ(String title,double price)
// {
// this.title = title;
// this.price = price;
// }
//
public void setPrice(double price) {
this.price = price;
}
public double getPrice() {
return price;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
@Override
public String toString() {
// TODO Auto-generated method stub
// return "这是一本书";
return "图书"+this.title+"价格"+this.price;
}
}



