37.
Java里所谓的区间都是含左不含右的 比如说random;
38.
反射调用域为域赋值的程序:
packagecom.shengsiyuan.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectTester
{
// 该方法实现对Customer对象的拷贝操作
public Object copy(Objectobject)throws Exception
{
Class<?> classType =object.getClass();
Object objectCopy =classType.getConstructor(new Class[] {})
.newInstance(new Object[] {});
// 获得对象的所有成员变量
Field[] fields =classType.getDeclaredFields();
for (Field field : fields)
{
String name = field.getName();
String firstLetter = name.substring(0,1).toUpperCase();//将属性的首字母转换为大写
String getMethodName = "get" + firstLetter + name.substring(1);
String setMethodName = "set" + firstLetter + name.substring(1);
Method getMethod =classType.getMethod(getMethodName,
new Class[] {});
Method setMethod =classType.getMethod(setMethodName,
new Class[] { field.getType() });
Object value = getMethod.invoke(object, new Object[] {});
setMethod.invoke(objectCopy, new Object[] { value });
}
// 以上两行代码等价于下面一行
// Object obj2 = classType.newInstance();
// System.out.println(obj);
return objectCopy;
}
public static void main(String[] args)throws Exception
{
Customer customer = new Customer("Tom", 20);
customer.setId(1L);
ReflectTester test = new ReflectTester();
Customer customer2 = (Customer)test.copy(customer);
System.out.println(customer2.getId() +"," +customer2.getName() +","
+ customer2.getAge());
}
}
class Customer
{
private Longid;
private Stringname;
private int age;
public Customer()
{
}
public Customer(Stringname,int age)
{
this.name = name;
this.age = age;
}
public Long getId()
{
return id;
}
public void setId(Long 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;
}
}
39.
反射可以破坏私有方法的封装性。看例子41
40.
Invoke 方法返回什么呢? 它返回一个Object 对象,它代表的是目标方法的返回类型(返回值)
比如说调用的方法返回类型为 void ;则它的值就是null;
如果返回类型是String 就会返回向同类型的数据,别忘了类型转换;
package com.jianjian2.Reflection;
import java.lang.reflect.Method;
public class PrivateDemo
{
public static void main(String[] args)throws Exception
{
Demo demo = new Demo();
Class<?> c = demo.getClass();
Method method = c.getDeclaredMethod("method",new Class[]{String.class});
Object obj = method.invoke(demo,new Object[]{"zhangsan"});
System.out.println(obj);
}
}
class Demo
{
public Stringmethod(String name)
{
System.out.println("hello:"+ name);
return name;
}
}
结果:
hello :zhangsan
zhangsan
41.
说过用反射可以破坏调用方法的封装性,实现这种操作是通过Method从它的父类 java.lang.reflect.AccessibleObject中继承的
public voidsetAccessible(boolean flag)方法来实现的,
该方法接受一个Boolean类型的标识,如果接受的true,那么方法就会对目标方法采取压制modifier(access modifier),即会忽略掉目标方法的访问修饰符,那么就可以调用私有方法了,如果传入的是false,则不会采取任何操作,默认都是false;
42.
在Class类中对于调用方法或属性都提供了多种形式,带
Declarde的方法可以返回所有的,而不带则只能返回public的;注意区分
43.
下面是如何利用反射操作私有属性,与方法不同的是属性都应该是要设置和调用的,所以应该有设置,和调用两个方法存在;注意一下Java的默认协定,对属性的操作一般都是set 与 get方法,所以查找的时候不能盲目。
总体来说也是采用和调用私有方法相同的形式,因为AccessibleObject有三个默认的子类(subclass)Constructor、Field、Method;
要求,调用类中的字符串私有属性 zhangsan ,并修改其为lisi:
调用的时候不会出现问题,关键是访问的限制:
package com.jianjian2.Reflection;
import java.lang.reflect.Field;
public class PrivateFieldTest
{
public static void main(String[] args)throws Exception
{
PrivateField test = new PrivateField();
Class<?> c = test.getClass();
Field field = c.getDeclaredField("name");
// System.out.println(field);会打印出具体的属性名称,但是我定义成了私有的也就不能调用了;
field.setAccessible(true);//在修改前进行调用;
field.set(test,"lisi");//该方法用来修改属性;
System.out.println(test.getName());
}
}
44.
包装类型的.TYPE = 原生类型的Class类型
Integer.TYPE = int
package com.jianjian2.Reflection;
public class TypeTest
{
public static void main(String[] args)
{
System.out.println(Integer.TYPE);
Class<?> c = Integer.TYPE;
System.out.println(c);
}
}
45.
为什么Java不允许返回类型不同而参数类型,参数数量都一样的重载方法呢?
因为当我们调用方法时,如果不打算调用返回值,而是单纯的调用方法,那么Java虚拟机就不知道该调用哪个方法了!!!
所以不允许这种重载的存在。
46.
关于代理模式
强调一点的是引用类型在没有生成实例之前,都是null型的,
比如说 我定义了一个 public Person person ;
如果此刻打印person 肯定为null;
可以 person= new Person();
就不会为空了;
47.
动态代理没有学好,还要巩固
48.
开始学习 Java Annotation Java注解的学习
虽然不被鼓励
调用Java.util.Date,新建一个date实例可以返回当前系统的时间
package com.jianjian.Annotation;
import java.util.Date;
public class DateTest
{
public static void main(String[] args)
{
Date date = new Date();
System.out.println(date);
}
}