先来说说什么是反射?
反射的意思就是动态的获取程序信息以及动态的调用对象。
1.反射的基础应用(取得类类型的三种方法)
package cn.java.learn
public class Reflect{
public static void main(String[] args){
//第一种
Book b1=new Book();
System.out.println(b1.getClass());
//第二种
Class<?> cls1=Book.class;
System.out.println(cls1);
//第三种
Class<?> cls=null;
try {
cls = Class.forName("cn.java.learn.Book");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println(cls);
}
class Book{
}
最后结果都输出
分析总结:这三种方法都可以取得类类型,比较常用的是第3种
第1种:对象名.getClass()
第2种:类名.class
第3种:Class.forName(String className)
2.利用反射进行实例化对象
package cn.java.learn;
public class Reflect{
public static void main(String[] args) throws Exception{
Class<?> cls=Class.forName("cn.java.learn.Book2");
//相当于使用new无参构造方法
Object obj=cls.newInstance();
}
}
class Book2{
public Book2(){
System.out.println("我是book2");
}
}
最后输出
3.工厂设计模式 new一个对象,利用反射进行解耦合
interface Fruit{
public void eat();
}
class Apple implements Fruit{
@Override
public void eat(){
System.out.println("** 吃苹果 **");
}
}
class Orange implements Fruit{
@Override
public void eat() {
System.out.println("** 吃橘子 **");
}
}
class Factory{
//声明一个静态的初始化方法
public static Fruit getInstance(String className){
Fruit fruit=null;
try{
//Class.forName返回一个object的对象,在强转成fruit
fruit=(Fruit)(Class.forName(className).newInstance());
}catch(Exception e){
e.printStackTrace();
}
return fruit;
}
}
package cn.java.learn;
public class Reflect{
public static void main(String[] args){
//这里写橘子就是橘子,写苹果就是苹果
Fruit apple=Factory.getInstance("cn.java.learn.Orange");
apple.eat();
}
}
最后输出
4.利用反射调用有参构造方法
class Book4{
private String title;
private double price;
public Book4(String title,double price)
{
this.title=title;
this.price=price;
}
public String toString()
{
return "图书名称:"+this.title+",图书价格:"+this.price;
}
}
package cn.java.learn;
public class Reflect {
public static void main(String[] args)throws Exception{
Class<?> cls=Class.forName("cn.java.learn.Book4");
//有参构造需要告诉类型
Constructor<?> con=cls.getConstructor(String.class,double.class);
//调用构造 这里返回的是object类型的你转成Book4也行直接输出也行
Object obj=con.newInstance("java程序设计",50.5);
System.out.println(obj);
}
}
最后输出
5.利用反射调用类中的方法
public static void main(String[] args)throws Exception{
Class<?> cls=Class.forName("cn.java.learn.Book5");
Object obj=cls.newInstance();
//类中有setTitle()和getTitile()
Method set=cls.getMethod("setTitle", String.class);
Method get=cls.getMethod("getTitle");
set.invoke(obj, "c++程序设计");
System.out.println(get.invoke(obj));
}
class Book5{
public Book5()
{
}
private String title;
public String getTitle()
{
return this.title;
}
public void setTitle(String title)
{
this.title=title;
}
}
输出
6.利用反射来取得类中的字段
反射很强大可以给你取消属性的封装
public static void main(String[] args)throws Exception{
Class<?> cls=Class.forName("cn.java.learn.Book6");
Object obj=cls.newInstance();
Field titleFiled=cls.getDeclaredField("title");
//设置取消封装
titleFiled.setAccessible(true);
titleFiled.set(obj, "Book6");
System.out.println(titleFiled.get(obj));
}
class Book6{
private String title;
}
输出