一、认识反射:
Object类里面提供有一个方法,用于取得Class对象:public final Class<?>getClass();
范例:
public class TestDemo{
public static main(String []args) throws Exception{
Date date = new Date();//产生对象
System.out.println(date.getClass());
}
}
运行结果为:class java.util.Date;
发现调用getClass()方法后的输出就输出了类的完整名称,等于找到了对象的出处。
Class类对象实例化:
java.lang.Class是一个类,这个类是反射操作的源头,即:所有的反射都要从此类开始进行,此类有三种实例化方式:
1.调用Object类中的getClass()方法
eg:
public static void main(String []args)throws Exception{
Date date = new Date();//产生对象
Class<?> cls = date.getClass();
System.out.println(cls);
}
2.第二种:使用“类class取得”
eg:
public static void main(String []args) throws Exception{
Class<?> cls = Date.class;
System.out.println(cls);
}
输出结果与上面相同
之前是产生了类的实例化对象之后取得的Class类对象,但是此时并没有实例化对象的产生。
3.第三种:调用Class类提供的一个方法:
实例化Class对象:public static Class<?>forName(String className);
eg:
public static void main(String[] args) throws Exception{
Class<?> cls = Class.forName("java.util.Date");
System.out.println(cls);
}
此时可以不使用import语句导入一个明确的类,而类名称是采用字符串的形式进行描述的。
二、反射实例化对象:
当拿到一个类时候,肯定要直接使用关键字new进行对象的实例化操作,这属于习惯性动作,但是如果有了Class类对象,就可以利用发射实现对象实例化操作。
实例化对象方法:public T newInstance()throws InstantiationException,Illegal
范例:利用反射实例化对象
package cn.mldn.demo;
class Book{
public Book(){
System.out.println("*****Book类的无参构造方法*****");
}
@Override
public String toString(){
return "这是一本书";
}
}
public class TestDemo{
public static void main(String[] args) throws Exception{
Class<?> cls = Class.forName("cn.mldn.demo.Book");//相当于找到Book类
Object obj = cls.newInstance();//相当于使用new调用无餐构造实例化
Book book = (Book) obj;//向下转型
System.out.println(book);
}
}
有了反射之后,进行对象实例化的操作不再只是单独的依靠关键字new完成了,反射也可以完成,但是这并不表示new被完全取代了。
在任何的开发之中,new是造成耦合的最大元凶,一切的耦合都起源于new。
范例:观察工厂设计模式
interface Fruit{
public void eat();
}
class Apple implements Fruit{
@Override
public void eat(){
System.out.println("吃苹果!");
}
}
class Factory{
public static Fruit getInstance(String className){
if("apple".equals(className)){
return new Apple();
}
return null;
}
}
public class TestFactory{
public static void main(String []args){
Fruit f = Factory.getInstance("apple");
f.eat();
}
}
如果此时增加了Fruit接口子类,就表示程序要修改工厂类。
interface Fruit{
public void eat();
}
class Apple implements Fruit{
@Override
public void eat(){
System.out.println("吃苹果!");
}
}
class Banana implements Fruit{
@Override
public void eat(){
System.out.println("吃香蕉!");
}
}
class Factory{
public static Fruit getInstance(String className){
if("apple".equals(className)){
return new Apple();
}else if("banana".equals(className)){
return new Banana();
}
return null;
}
}
public class TestFactory{
public static void main(String []args){
Fruit f = Factory.getInstance("apple");
f.eat();
}
}
每增加一个类就要去修改工厂类,那么如果我们随时都可能增加子类怎么办?
因为工厂类中的对象都是通过关键字new直接实例化的,而new就成了所有问题的关键点。要想解决这一问题,就只能依靠反射来完成。
interface Fruit{
public void eat();
}
class Apple implements Fruit{
@Override
public void eat(){
System.out.println("吃苹果!");
}
}
class Banana implements Fruit{
@Override
public void eat(){
System.out.println("吃香蕉!");
}
}
class Factory{
public static Fruit getInstance(String className){
Fruit f = null;
try{
f = (Fruit)Class.forName(className).newInstance();
}catch(Exception e){
return f;
}
}
}
public class TestFactory{
public static void main(String []args){
Fruit f = Factory.getInstance("cn.mldn.test.Apple");
f.eat();
}
}
此时的程序就真正完成了解耦合的目的,而且可扩展性非常的强。
注意:反射的所有泛型都是"?"
Object类里面提供有一个方法,用于取得Class对象:public final Class<?>getClass();
范例:
public class TestDemo{
public static main(String []args) throws Exception{
Date date = new Date();//产生对象
System.out.println(date.getClass());
}
}
运行结果为:class java.util.Date;
发现调用getClass()方法后的输出就输出了类的完整名称,等于找到了对象的出处。
Class类对象实例化:
java.lang.Class是一个类,这个类是反射操作的源头,即:所有的反射都要从此类开始进行,此类有三种实例化方式:
1.调用Object类中的getClass()方法
eg:
public static void main(String []args)throws Exception{
Date date = new Date();//产生对象
Class<?> cls = date.getClass();
System.out.println(cls);
}
2.第二种:使用“类class取得”
eg:
public static void main(String []args) throws Exception{
Class<?> cls = Date.class;
System.out.println(cls);
}
输出结果与上面相同
之前是产生了类的实例化对象之后取得的Class类对象,但是此时并没有实例化对象的产生。
3.第三种:调用Class类提供的一个方法:
实例化Class对象:public static Class<?>forName(String className);
eg:
public static void main(String[] args) throws Exception{
Class<?> cls = Class.forName("java.util.Date");
System.out.println(cls);
}
此时可以不使用import语句导入一个明确的类,而类名称是采用字符串的形式进行描述的。
二、反射实例化对象:
当拿到一个类时候,肯定要直接使用关键字new进行对象的实例化操作,这属于习惯性动作,但是如果有了Class类对象,就可以利用发射实现对象实例化操作。
实例化对象方法:public T newInstance()throws InstantiationException,Illegal
范例:利用反射实例化对象
package cn.mldn.demo;
class Book{
public Book(){
System.out.println("*****Book类的无参构造方法*****");
}
@Override
public String toString(){
return "这是一本书";
}
}
public class TestDemo{
public static void main(String[] args) throws Exception{
Class<?> cls = Class.forName("cn.mldn.demo.Book");//相当于找到Book类
Object obj = cls.newInstance();//相当于使用new调用无餐构造实例化
Book book = (Book) obj;//向下转型
System.out.println(book);
}
}
有了反射之后,进行对象实例化的操作不再只是单独的依靠关键字new完成了,反射也可以完成,但是这并不表示new被完全取代了。
在任何的开发之中,new是造成耦合的最大元凶,一切的耦合都起源于new。
范例:观察工厂设计模式
interface Fruit{
public void eat();
}
class Apple implements Fruit{
@Override
public void eat(){
System.out.println("吃苹果!");
}
}
class Factory{
public static Fruit getInstance(String className){
if("apple".equals(className)){
return new Apple();
}
return null;
}
}
public class TestFactory{
public static void main(String []args){
Fruit f = Factory.getInstance("apple");
f.eat();
}
}
如果此时增加了Fruit接口子类,就表示程序要修改工厂类。
interface Fruit{
public void eat();
}
class Apple implements Fruit{
@Override
public void eat(){
System.out.println("吃苹果!");
}
}
class Banana implements Fruit{
@Override
public void eat(){
System.out.println("吃香蕉!");
}
}
class Factory{
public static Fruit getInstance(String className){
if("apple".equals(className)){
return new Apple();
}else if("banana".equals(className)){
return new Banana();
}
return null;
}
}
public class TestFactory{
public static void main(String []args){
Fruit f = Factory.getInstance("apple");
f.eat();
}
}
每增加一个类就要去修改工厂类,那么如果我们随时都可能增加子类怎么办?
因为工厂类中的对象都是通过关键字new直接实例化的,而new就成了所有问题的关键点。要想解决这一问题,就只能依靠反射来完成。
interface Fruit{
public void eat();
}
class Apple implements Fruit{
@Override
public void eat(){
System.out.println("吃苹果!");
}
}
class Banana implements Fruit{
@Override
public void eat(){
System.out.println("吃香蕉!");
}
}
class Factory{
public static Fruit getInstance(String className){
Fruit f = null;
try{
f = (Fruit)Class.forName(className).newInstance();
}catch(Exception e){
return f;
}
}
}
public class TestFactory{
public static void main(String []args){
Fruit f = Factory.getInstance("cn.mldn.test.Apple");
f.eat();
}
}
此时的程序就真正完成了解耦合的目的,而且可扩展性非常的强。
注意:反射的所有泛型都是"?"