1.Point p1=new Point(8,8);
称p1为Point对象的引用
p1引用了一个点的对象,p1在栈内存,Point(8,8)在堆内存。
Point p2=p1;
p2.x=10;
输出p1.x=10;
p2与p1引用了同一个对象
2.静态函数只能访问静态成员
也就是不是静态成员,静态函数不能访问
3.反射给我一个感觉就是它是倒着来的,我们通常调用方法或者属性是"对象.方法/对象.属性"。但是反射是来了一个Method或Field对象,指定好方法或属性后,来哪个对象,执行哪个对象的东西,类似对象附属于方法存在一样。
先记下类的类类型的使用:
public static void main(String[] args) {
Class c = "hello".getClass();
Method[] ms = c.getMethods();
for(int i=0;i<ms.length;i++){
System.out.print(ms[i].getReturnType()+" "+ms[i].getName()+" ");
Class[] paramsType = ms[i].getParameterTypes();
for(int j=0;j<paramsType.length;j++){
System.out.print(paramsType[j].getName()+",");
}
System.out.println();
}
System.out.println("=======================================");
Constructor[] constructors = c.getConstructors();
for(int i=0;i<constructors.length;i++){
System.out.println(constructors[i].getName());
Class[] paramsType=constructors[i].getParameterTypes();
for (Class param : paramsType) {
System.out.print("("+param.getName());
}
System.out.println(")");
}
System.out.println();
System.out.println("=======================================");
Package packages=c.getPackage();
System.out.println(packages.getName());
}
开始讨论反射代码:我理解的核心是:指定方法,不同的对象产生不同的输出
方法的反射,这里实现一个标准JavaBean下通过对象和属性名(getter)获得值
User.java: 一个标准的JavaBean=每个属性都有get/set方法,有无参数构造函数
public class User {
private int id;
private String name;
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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 User(int id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
public User() {
super();
}
}
UserService.java:
import java.lang.reflect.Method;
public class UserService {
public Object getValueByPropertyName(String propertyName,Object object){
String methodName = "get"+propertyName.substring(0,1).toUpperCase()+propertyName.substring(1);
Class c = User.class;
try {
Method method = c.getMethod(methodName, new Class[]{});
Object value = method.invoke(object, new Object[]{});
return value;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
①为了获得方法名,先获得类的类类型
c.getMethod()中第一个参数为函数名,第二个为形参列表,反射多用于参数列表为空的情况
②方法反射的核心:
method.invoke(对象,实参列表);
在这里也就体现了是指定了相同方法,不同对象产生不同值
③返回Object对象
Main:
public static void main(String[] args) {
User user1 = new User(1,"Zhangsan",11);
UserService us = new UserService();
System.out.println((Integer)us.getValueByPropertyName("age", user1));
User user2 = new User(2,"Lisi",22);
System.out.println((String)us.getValueByPropertyName("name", user2));
}
输出:
11
Lisi
4.成员变量的反射:
指定变量,变动对象:
/*
* String转大写int 加100
*/
public void changeValue(Object object){
Class c = User.class;
Field[] fields = c.getDeclaredFields();
try {
for (Field field : fields) {
if(field.getType()==String.class){
field.setAccessible(true);
String oldValue;
oldValue = (String)field.get(object);
field.set(object, oldValue.toUpperCase());
}
else if(field.getType()==int.class){
field.setAccessible(true);
field.set(object, (Integer)field.get(object)+100);
}
else{
System.out.println();
}
}
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
注意setAccessible(true);