Hello, Hello, everyone! I am a programmer hooligan! To share with you today is mainly based learning framework - reflection.
First, the use of the class Class
1, the object-oriented world, all things are objects.
Note: java language, static members, common data types are not objects.
Class is an object, an object instance of the class is a class java.lang.Class.
Foo foo1 = new Foo (); // Foo instance object
Any instance of a class is a Class object instance object that represents three ways:
Class c1 = Foo.class;
Class c2 = foo1.getClass();
Class c3 = null; c3 = Class.forName("com.imooc.reflect.Foo");
All things are objects, classes are objects, is an example of an object class Class, we call this object class type class.
Two, Java dynamic class loading
Class.forName ( "class name")
-
Not only represents a class of class type, said dynamic load classes.
Please distinguish compile and run
Compile time when class is loaded static loading classes, the runtime classes are loaded dynamically loaded class.
note:
-
Create a new object is a static load class, at compile time you need to load all of the classes may be used.
Can solve this problem by dynamically load classes.
Officer {class
public static void main (String [] args) {
IF ( "Word" .equals (args [0])) {
Word Word = new new Word ();
word.start ();
}
IF ( "Excel." the equals (args [0])) {
Excel Excel Excel new new = ();
excel.start ();
}
}
}
class OfficeBetter {
public static void main (String [] args) {
the try {
// dynamically load classes at runtime loading
class C = the Class.forName (args [0]);
// class type by creating the class object
OfficeAble OA = (OfficeAble) c.newInstance ();
oa.start ();
} the catch (Exception E) {
e.printStackTrace ();
}
}
}
Class Word the implements OfficeAble {
public void Start () {
system.out.printIn ( "Word ------");
}
}
class Excel the implements OfficeAble {
public void Start () {
system.out.printIn ( "Excel ------");
}
}
// summary: If only Word class, the class compiled directly Office, the background error, suggesting no Excel class; using dynamic class loading, you do not need every time recompile OfficeBetter class.
Three, Java methods to obtain information
{class ClassUtil public
public static void printClassMessage (Object obj) {
// the class information acquired
Class C = obj.getClass ();
// get a class name
System.out.printIn ( "Class Name:" + c.getName ());
/ *
* method class, method object table
* a member method is a method object
* getMethod () method to get all public functions, including the parent class inherited
* getDeclaredMethods (); Get all class declaration method
* /
method, [] MS = c.getMethods ();
for (int I = 0; I <ms.length; I ++) {
// get the return value of type class type
class returnType = ms [i]. getReturnType ();
System.out.printIn (returnType.getName () + "");
// get the name of the method
Of System.out.print (MS [I] .getName () + "(");
// --- type acquisition parameters obtained parameter list is a type of class types
Class [] paramTypes = ms [i ] .getParameterTypes ( );
for (Class Class1: paramTypes) {
of System.out.print (class1.getName () + ",");
}
of System.out.print ( ")");
}
}
}
Package com.wnf.reflect;
public ClassDemo01 {class
public static void main (String [] args) {
String name = "the Hello World!";
ClassUtil.printClassMessage (name);
ClassDemo02 demo2 new new ClassDemo02 = ();
ClassUtil.printClassMessage (demo2);
}
}
Four, Java constructor of member variables get information
Member variables are objects
java.lang.reflect.Filed
Filed类封装了关于成员变量的操作
getFileds()方法获取的是所有的public的成员变量的信息
getDeclaredFileds获取的是该类自己声明的成员变量的信息
Filed[] fs = c.getDeclaredFileds();
for(Filed filed:fs){
//得到成员变量的类型的类类型
Class filedType = filed.getType();
String typeName = fileType.getName();
//得到成员变量的名称
String filedName = filed.getName();
System.out.printLn(typeName+""+filedName);
}
public static void printFieldMessage(Object obj) {
//获取成员变量的信息
Class c = obj.getClass();
Field[] fs = c.getFields();
for(Field field : fs){
Class fieldType = field.getType();
String typeName= fieldType.getSimpleName();
String fieldName = field.getName();
System.out.println(typeName+" "+fieldName);
}
}
//getConstructors()获取public的构造函数
//getDeclaredConstructors()获取该类自己声明的构造函数
public static void printConMessage(Object obj){
//获取该类的构造函数
Class c = obj.getClass();
Constructor[] cr = c.getConstructors();
for (Constructor constructor : cr) {
System.out.print(constructor.getName()+"(");
Class[] paramTypes = constructor.getParameterTypes();
for (int j=0; j<paramTypes.length;j++) {
if(j==paramTypes.length-1){
System.out.print(paramTypes[j].getSimpleName());
}else{
System.out.print(paramTypes[j].getSimpleName()+",");
}
}
System.out.println(")");
}
}
五、Java方法反射的基本操作
方法的反射
1、如何获取某个方法
方法的名称和方法的参数列表才能唯一决定某个方法
2、方法反射的操作
method.invoke(对象
,参数列表)
package com.imooc.reflect;
import java.lang.reflect.Method;
public class MethodDemo1 {
public static void main(String[] args) {
//要获取print(int ,int )方法 1.要获取一个方法就是获取类的信息,获取类的信息首先要获取类的类类型
A a1 = new A();
Class c = a1.getClass();
/*
* 2.获取方法 名称和参数列表来决定
* getMethod获取的是public的方法
* getDelcaredMethod自己声明的方法
*/
try {
//Method m = c.getMethod("print", new Class[]{int.class,int.class});
Method m = c.getMethod("print", int.class,int.class);
//方法的反射操作
//a1.print(10, 20);方法的反射操作是用m对象来进行方法调用 和a1.print调用的效果完全相同
//方法如果没有返回值返回null,有返回值返回具体的返回值
//Object o = m.invoke(a1,new Object[]{10,20});
Object o = m.invoke(a1, 10,20);
System.out.println("==================");
//获取方法print(String,String)
Method m1 = c.getMethod("print",String.class,String.class);
//用方法进行反射操作
//a1.print("hello", "WORLD");
o = m1.invoke(a1, "hello","WORLD");
System.out.println("===================");
// Method m2 = c.getMethod("print", new Class[]{});
Method m2 = c.getMethod("print");
// m2.invoke(a1, new Object[]{});
m2.invoke(a1);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class A{
public void print(){
System.out.println("helloworld");
}
public void print(int a,int b){
System.out.println(a+b);
}
public void print(String a,String b){
System.out.println(a.toUpperCase()+","+b.toLowerCase());
}
}
六、通过反射了解集合泛型的本质
package com.imooc.reflect;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class MethodDemo4 {
public static void main(String[] args) {
ArrayList list = new ArrayList();
ArrayList<String> list1 = new ArrayList<String>();
list1.add("hello");
//list1.add(20);错误的
Class c1 = list.getClass();
Class c2 = list1.getClass();
System.out.println(c1 == c2);
//反射的操作都是编译之后的操作
/*
* c1==c2结果返回true说明编译之后集合的泛型是去泛型化的
* Java中集合的泛型,是防止错误输入的,只在编译阶段有效,
* 绕过编译就无效了
* 验证:我们可以通过方法的反射来操作,绕过编译
*/
try {
Method m = c2.getMethod("add", Object.class);
m.invoke(list1, 20);//绕过编译操作就绕过了泛型
System.out.println(list1.size());
System.out.println(list1);
/*for (String string : list1) {
System.out.println(string);
}*///现在不能这样遍历
} catch (Exception e) {
e.printStackTrace();
}
}
}