您的位置:首页 > 编程语言 > Java开发

java中Class类和反射机制

2017-08-22 21:22 246 查看
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为JAVA语言的反射机制。
 

1.取得Class类的对象的三种方法

      取得Class对象:public final Class<?> getClass(),反射之中的所有泛型都定义为?,返回值都是Object。

通过Object类的getClass()方法取得

[java]
view plain
copy

print?

<span style="color:#000000;">class Person{}  
 public class TestDemo{  
     public static void main(String[] args) throws Exception{  
        Person per = new Person();  
        Class<?> cls = per.getClass();  
        System.out.println(cls.getName());  
    }  
}</span>  

<span style="color:#000000;">class Person{}
public class TestDemo{
public static void main(String[] args) throws Exception{
Person per = new Person();
Class<?> cls = per.getClass();
System.out.println(cls.getName());
}
}</span>

 

使用“类.Class”取得

[java]
view plain
copy

print?

<span style="font-size:12px;"> class Person{}  
 public class TestDemo{  
     public static void main(String[] args) throws Exception{  
        Class<?> cls = Person.class;  
        System.out.println(cls.getName());  
    }  
}</span>  

<span style="font-size:12px;"> class Person{}
public class TestDemo{
public static void main(String[] args) throws Exception{
Class<?> cls = Person.class;
System.out.println(cls.getName());
}
}</span>

 

使用Class类内部定义的一个static方法
   
取得Class类对象:public static Class<?>forName(String className) throws ClassNotFoundException

[java]
view plain
copy

print?

class Person{}  
 public class TestDemo{  
     public static void main(String[] args) throws Exception{  
    Class<?> cls = Class.forName("Person");//取得Class对象  
        System.out.println(cls.getName());  
    }  
}  

class Person{}
public class TestDemo{
public static void main(String[] args) throws Exception{
Class<?> cls = Class.forName("Person");//取得Class对象
System.out.println(cls.getName());
}
}



2.通过反射实例化对象

   
通过反射实例化对象:public T newInstance () throws InstantiationException,IllegalAccessException

[java]
view plain
copy

print?

class Person{  
     public String toString(){  
         return "Person Class Instance.";  
     }  
 }  
 public class TestDemo{  
     public static void main(String[] args) throws Exception{  
    Class<?> cls = Class.forName("Person");//取得Class对象  
        Object obj = cls.newInstance();  //实例化对象,和使用关键字new一样  
        Person per = (Person) obj ; //向下转型  
        System.out.println(per);  
    }  
 }  

class Person{
public String toString(){
return "Person Class Instance.";
}
}
public class TestDemo{
public static void main(String[] args) throws Exception{
Class<?> cls = Class.forName("Person");//取得Class对象
Object obj = cls.newInstance();  //实例化对象,和使用关键字new一样
Person per = (Person) obj ; //向下转型
System.out.println(per);
}
}


范例:工厂模式

[java]
view plain
copy

print?

<span style="font-size:12px;">interface Fruit{  
    public void eat();  
}  
class Apple implements Fruit{  
    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 FactoryDemo {  
    public static void main(String[] args) {  
        Fruit f = Factory.getInstance("apple");  
        f.eat();  
    }  
}</span>  

<span style="font-size:12px;">interface Fruit{
public void eat();
}
class Apple implements Fruit{
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 FactoryDemo {
public static void main(String[] args) {
Fruit f = Factory.getInstance("apple");
f.eat();
}
}</span>


    在这个工厂设计模式之中有一个最大的问题:如果现在接口的子类增加了,那么工厂类肯定需要修改,这是它所面临的最大问题,而这个最大问题造成的关键性病因是new,那么如果说现在不使用关键字new了,变为了反射机制呢?

 

[java]
view plain
copy

print?

interface Fruit{  
    public void eat();  
}  
class Apple implements Fruit{  
    public void eat(){  
        System.out.println("吃苹果。");  
    }  
}  
class Orange implements Fruit{  
    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) {  
            e.printStackTrace();  
        }   
        return f ;  
    }  
}  
public class FactoryDemo {  
    public static void main(String[] args) {  
        Fruit f = Factory.getInstance("Orange");  
        f.eat();  
    }  
}  

interface Fruit{
public void eat();
}
class Apple implements Fruit{
public void eat(){
System.out.println("吃苹果。");
}
}
class Orange implements Fruit{
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) {
e.printStackTrace();
}
return f ;
}
}
public class FactoryDemo {
public static void main(String[] args) {
Fruit f = Factory.getInstance("Orange");
f.eat();
}
}



3.调用构造方法


[align=center][/align]

[align=center][/align]

[align=center][/align]

<
fba8
/tr>
编号
方法名称返回值类型说明
1
getConstructors()
Constructor数组
获取所有权限为public的构造方法
2
getConstructor(Class<?>…parameterTypes)
Constructor对象
获取权限为public的指定构造方法
3
getDeclaredConstructors()
Constructor数组
获得所有构造方法,按声明顺序返回
4
getDeclaredConstructor(Class<?>…parameterTypes)
Constructor对象
获得指定的构造方法
[java]
view plain
copy

print?

<span style="font-size:12px;">import java.lang.reflect.Constructor;  
 class Person{  
     public Person(){}  
     public Person(String name){}  
     public Person(String name , int age){}  
 }  
 public class TestDemo{  
     public static void main(String[] args) throws Exception{  
        Class<?> cls = Class.forName("Person");//取得Class对象  
        Constructor<?> cons []  = cls.getConstructors();  //取得全部构造  
        for(int x = 0 ; x < cons.length ; x ++){  
            System.out.println(cons[x]);  
        }  
    }  
 }</span>  

<span style="font-size:12px;">import java.lang.reflect.Constructor;
class Person{
public Person(){}
public Person(String name){}
public Person(String name , int age){}
}
public class TestDemo{
public static void main(String[] args) throws Exception{
Class<?> cls = Class.forName("Person");//取得Class对象
Constructor<?> cons []  = cls.getConstructors();  //取得全部构造
for(int x = 0 ; x < cons.length ; x ++){
System.out.println(cons[x]);
}
}
}</span>


范例:调用有参数的构造方法

[java]
view plain
copy

print?

import java.lang.reflect.Constructor;  
 class Person{  
     private String name;  
     private int age ;  
     public Person(String name , int age){  
         this.name = name ;  
         this.age = age ;  
     }  
     public String toString(){  
         return "Person [name="+name+",age="+age+"]" ;  
     }  
 }  
 public class TestDemo{  
     public static void main(String[] args) throws Exception{  
    Class<?> cls = Class.forName("Person");//取得Class对象  
        //取得指定参数类型的构造方法  
    Constructor<?> cons = cls.getConstructor(String.class,int.class);  
        Object obj = cons.newInstance("张三",20);//为构造方法传递参数  
        System.out.println(obj);  
     }  
 }  

import java.lang.reflect.Constructor;
class Person{
private String name;
private int age ;
public Person(String name , int age){
this.name = name ;
this.age = age ;
}
public String toString(){
return "Person [name="+name+",age="+age+"]" ;
}
}
public class TestDemo{
public static void main(String[] args) throws Exception{
Class<?> cls = Class.forName("Person");//取得Class对象
//取得指定参数类型的构造方法
Constructor<?> cons = cls.getConstructor(String.class,int.class);
Object obj = cons.newInstance("张三",20);//为构造方法传递参数
System.out.println(obj);
}
}



4.调用普通方法

[align=center] [/align]
[align=center] [/align]
[align=center] [/align]

编号
方法名称返回值类型说明
1
getMethods()
Method数组
获取所有权限为public的方法
2
getMethod(String name,Class<?>…parameterTypes)
Method对象
获取权限为public的指定方法
3
getDeclaredMethods()
Method数组
获得所有方法,按声明顺序返回
4
getDeclaredMethod(String name,Class<?>…parameterTypes)
Method对象
获得指定的方法
 

[java]
view plain
copy

print?

import java.lang.reflect.Constructor;  
import java.lang.reflect.Method;  
 class Person{  
    private String name;  
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  
 }  
 public class TestDemo{  
     public static void main(String[] args) throws Exception{  
    Class<?> cls = Class.forName("Person");//取得Class对象  
        Method met [] = cls.getMethods();  
        for(int x = 0 ; x < met.length ; x ++){  
            System.out.println(met[x]);  
        }  
     }  
 }  

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
class Person{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class TestDemo{
public static void main(String[] args) throws Exception{
Class<?> cls = Class.forName("Person");//取得Class对象
Method met [] = cls.getMethods();
for(int x = 0 ; x < met.length ; x ++){
System.out.println(met[x]);
}
}
}


    取得了Method类对象之后有一个最大的功能,就是可以利用反射调用类中的方法。调用方法:

public Object invoke(Object obj,Object…args) throws IllegalAccessException,IllegalArgumentException,InyocationTargetException

 

[java]
view plain
copy

print?

import java.lang.reflect.Method;  
 class Person{  
    private String name;  
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  
 }  
 public class TestDemo{  
     public static void main(String[] args) throws Exception{  
    Class<?> cls = Class.forName("Person");//取得Class对象  
        Object obj = cls.newInstance();  
        String attribute = "name"; //要调用类之中的属性  
Method setMet = cls.getMethod("set"+initcap(attribute),String.class);  
        //setName()  
        Method getMet = cls.getMethod("get"+initcap(attribute));  
        //getName()  
        setMet.invoke(obj, "张三");//等价于:Person对象.setName("张三");  
        System.out.println(getMet.invoke(obj));  
           //等价于:Person对象.getName()  
     }  
     public static String initcap(String str){  
     return str.substring(0,1).toUpperCase().concat(str.substring(1));  
     }  
 }  

import java.lang.reflect.Method;
class Person{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class TestDemo{
public static void main(String[] args) throws Exception{
Class<?> cls = Class.forName("Person");//取得Class对象
Object obj = cls.newInstance();
String attribute = "name"; //要调用类之中的属性
Method setMet = cls.getMethod("set"+initcap(attribute),String.class);
//setName()
Method getMet = cls.getMethod("get"+initcap(attribute));
//getName()
setMet.invoke(obj, "张三");//等价于:Person对象.setName("张三");
System.out.println(getMet.invoke(obj));
//等价于:Person对象.getName()
}
public static String initcap(String str){
return str.substring(0,1).toUpperCase().concat(str.substring(1));
}
}



5.调用成员

[align=center][/align]
[align=center] [/align]

[align=center][/align]

编号
方法名称返回值类型说明
1
getFields()
Field数组
获取所有权限为public的成员变量
2
getField(String name)
Field对象
获取权限为public的指定成员变量
3
getDeclaredFields()
Field数组
获得所有成员变量,按声明顺序返回
4
getDeclaredField(String name)
Field对象
获得指定的构造方法
[java]
view plain
copy

print?

<span style="font-size:12px;">import java.lang.reflect.Field;  
import java.lang.reflect.Method;  
 class Person{  
    private String name;  
 }  
 public class TestDemo{  
     public static void main(String[] args) throws Exception{  
        Class<?> cls = Class.forName("Person");//取得Class对象  
        Field field [] = cls.getDeclaredFields();  
        for(int x = 0 ; x < field.length ; x++) {  
            System.out.println(field[x]);  
            }  
        }  
     }</span>  

<span style="font-size:12px;">import java.lang.reflect.Field;
import java.lang.reflect.Method;
class Person{
private String name;
}
public class TestDemo{
public static void main(String[] args) throws Exception{
Class<?> cls = Class.forName("Person");//取得Class对象
Field field [] = cls.getDeclaredFields();
for(int x = 0 ; x < field.length ; x++) {
System.out.println(field[x]);
}
}
}</span>


在Field类之中提供了两个方法:

设置属性内容(类似于:对象.属性 = 内容):

public void set(Object obj,Object value) throws IllegalArgumentExcepiton,IllegalAccessException ;
取得属性内容(类似于:对象.属性):

public Object get(Object obj) throws IllegalArgumentException,IllegalAccessException
从类的开发要求而言,一直都强调之中类之中的属性必须封装,所以现在调用之前要想尽一切方法解除封装。

解除封装:public void setAccessible(boolean flag)throws SecurityException;

[java]
view plain
copy

print?

<span style="font-size:12px;">import java.lang.reflect.Field;  
 class Person{  
    private String name;  
 }  
 public class TestDemo{  
     public static void main(String[] args) throws Exception{  
    Class<?> cls = Class.forName("Person");//取得Class对象  
        Object obj = cls.newInstance();  //对象实例化属性才会分配空间  
        Field nameField  = cls.getDeclaredField("name"); //找到name属性  
        nameField.setAccessible(true);  
        nameField.set(obj,"张三");//Person对象.name = "张三"  
        System.out.println(nameField.get(obj));  
     }  
 }</span>  

<span style="font-size:12px;">import java.lang.reflect.Field;
class Person{
private String name;
}
public class TestDemo{
public static void main(String[] args) throws Exception{
Class<?> cls = Class.forName("Person");//取得Class对象
Object obj = cls.newInstance();  //对象实例化属性才会分配空间
Field nameField  = cls.getDeclaredField("name"); //找到name属性
nameField.setAccessible(true);
nameField.set(obj,"张三");//Person对象.name = "张三"
System.out.println(nameField.get(obj));
}
}</span>



6.其他可以通过反射访问的主要描述信息

[align=center][/align]

[align=center][/align]

[align=center][/align]

组成部分
访问方法返回值类型说明
包路径
getPackage()
Package对象
获得该类的存放路径
类名称
getName()
String对象
获得该类的名称
继承类
getSuperclass()
Class对象
获得该类的继承的类
实现接口
getInterfaces()
Class数组
获得该类实现的所有接口
内部类
getClasses()
getDeclaredClasses()
Class数组
获得所有权限为public的内部类
获得所有内部类
内部类的声明类
getDeclaringClass()
Class对象
如果该类为内部类,则返回它的成员类,否则返回null
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: