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

JAVA--反射(基础知识~~真的是基础的哦)

2015-07-18 22:18 555 查看
什么是Java反射机制

Java的反射机制是在程序运行时,能够完全知道任何一个类,及其它的属性和方法,并且能够任意调用一个对象的属性和方法。这种运行时的动态获取就是Java的反射机制。其实这也是Java是动态语言的一个象征。

用一句话来概括反射就是加载一个运行时才知道的类以及它的完整内部结构。

反射的包名为:

软件包 java.lang.reflect

提供类和接口,以获得关于类和对象的反射信息。

通过反射我们可以拿到需求的类的 属性

下面是获取对象的方法 ~~!前提是有这么一个类 我先写一个Animal 类

public class Animal {
private String name;
private int age;
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString() {
return "Animal [name=" + name + ", age=" + age + "]";
}
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
res
4000
ult = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Animal other = (Animal) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public void eat(){
System.out.println("Animal  :"+name+".."+age+"吃东西");
}
public void run(){
System.out.println("Animal  :"+name+".."+age+"奔跑吧小家伙!");
}
}


A:三种获取Class对象的方式

1:Person p = new Person();

Class c = p.getClass();

2:Class c2 = Person.class;

任意数据类型都具备一个class静态属性,看上去要比第一种方式简单.

3:将类名作为字符串传递给Class类中的静态方法forName即可

Class c3 = Class.forName(“Person”);

public class ClassDemo {
public static void main(String[] args) throws Exception {
Animal an = new Animal();//创建动物对象
Class c = an.getClass();//第一种方法
System.out.println("--------------");
//  任意数据类型都具备一个class静态属性,看上去要比第一种方式简单.
Class c1 = Animal.class;
System.out.println("---------------");
//将类名作为字符串传递给Class类中的静态方法forName即可                           //注意"Anima"是全类名包库包~~我这里偷懒了
Class c2 = Class.forName("Animal");//这是会跑异常的
}
}


4:第三种和前两种的区别

前两种你必须明确Person类型.

后面是给我这种类型的字符串就行.这种扩展更强.我不需要知道你的类.我只提供字符串,按照配置文件加载就可以了

B:获得类的构造方法与对象的创建

获取构造方法

getConstructors

getDeclaredConstructors

/*
*  获取构造方法
getConstructors
getDeclaredConstructors
创建对象
newInstance()
con.newInstance(“zhangsan", 20);

*/
public class ClassDemo {
public static void main(String[] args) throws Exception{
Class<?> c = Class.forName("Animal");   //拿到动物类

Constructor<?>[] con = c.getConstructors();//获取构造方法
/*
* getConstructors
public Constructor<?>[] getConstructors()
throws SecurityException返回一个包含某些 Constructor
对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。如果该类没有公共构造方法,
或者该类是一个数组类,或者该类反映一个基本类型或 void,则返回一个长度为 0 的数组。
注意,此方法返回 Constructor<T> 对象的数组(即取自此类构造方法的数组)时,
此方法的返回类型是 Constructor<?>[],不是 预期的 Constructor<T>[]。
此少量信息的返回类型是必需的,因为从此方法返回之后,该数组可能被修改以保存不同类的 Constructor
对象,而这将违反 Constructor<T>[] 的类型保证。

返回:
表示此类公共构造方法的 Constructor 对象数组
*/
Constructor<?>[] con1 = c.getDeclaredConstructors();
/*
* public Constructor<?>[] getDeclaredConstructors()
throws SecurityException返回 Constructor
对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。它们是公共、保护、默认(包)访问和私有构造方法。
返回数组中的元素没有排序,也没有任何特定的顺序。如果该类存在一个默认构造方法,则它包含在返回的数组中。
如果此 Class 对象表示一个接口、一个基本类型、一个数组类或 void,则此方法返回一个长度为 0 的数组。
*/
}
}


创建对象

newInstance()

/*
* 创建对象
newInstance()

*/
public class ClassDemo1 {
//
public static void main(String[] args) throws Exception {
Class<?> c = Class.forName("Animal");
c.newInstance();//获得了对象~~!就可以用方法了
// T newInstance() 创建此 Class 对象所表示的类的一个新实例。
System.out.println(c.newInstance());//打印对象 因为重写了toString 所以不会出现哈希值
//但是以为没有初始化所以为空
}
}


获取所有成员

getFields,getDeclaredFields

获取单个成员

getField,getDeclaredField

修改成员的值

set(Object obj,Object value)

/*
* 获取所有成员
getFields,getDeclaredFields
获取单个成员
getField,getDeclaredField
修改成员的值
set(Object obj,Object value)

*/
public class ClassDemo3 {
public static void main(String[] args) throws Exception {
Class <?>c = Class.forName("Animal");
c.newInstance();//获取对象
// Field[] getFields()
// 返回一个包含某些 Field 对象的数组,这些对象反映此
//Class 对象所表示的类或接口的所有可访问公共字段。
Field[] fields = c.getFields();//获得成员数组
// Field getField(String name)
// 返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。
Field field = c.getField("age");
// Field getDeclaredField(String name)
//   返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。
c.getDeclaredField("name");

}
}


获取所有方法

getMethods

getDeclaredMethods

获取单个方法

getMethod

getDeclaredMethod

/*
*  获取所有方法
getMethods
getDeclaredMethods
获取单个方法
getMethod
getDeclaredMethod
*/
public class ClassDemo4 {
public static void main(String[] args) throws Exception {
Class<?> c = Class.forName("cn.itcast.date_test.Animal");//获取类
// Method[] getMethods()
//返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口
//(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。
Method[] methods = c.getMethods();
// Method[] getDeclaredMethods()
// 返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,
//包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
Method[] declaredMethods = c.getDeclaredMethods();
System.out.println(methods[0]);

System.out.println("------------------");
// Method getMethod(String name, Class<?>... parameterTypes)
// 返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。
Method method = c.getMethod("run", null);
// Method getDeclaredMethod(String name, Class<?>... parameterTypes)
//返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
c.getDeclaredMethod("sleep", null);
System.out.println("-----------------");

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: