Java学习笔记十一

时间:2023-02-26 16:10:43


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);

     

   }

}