001package com.basilv.examples.java5; 002 003import java.lang.reflect.Array; 004import java.util.*; 005 006 007class BusinessEntity { 008 private Integer id; 009 010 public BusinessEntity(Integer id) { 011 this.id = id; 012 } 013 014 public Integer getId() { 015 return id; 016 } 017 018 public int getIdAsPrimitiveInt() { 019 return id; // Unboxing (Integer to int). What happens if id is null??? 020 } 021 022 @Override // Annotation (Java standard) 023 public String toString() { 024 return "Id:" + id; 025 } 026 027 public BusinessEntity getMyself() { 028 return this; 029 } 030 031 032} 033 034class PersonEntity extends BusinessEntity { 035 036 // Enumerated Type (enum) 037 // Can get list of values with AddressType.values(); 038 // Can get particular instance with AddressType.valueOf("Mailing"); 039 // Can even have abstract methods that particular enumerated value constant overrides. 040 public enum AddressType { 041 MAILING("Mailing", 1), 042 BILLING("Billing", 2); 043 044 private String displayName; 045 046 // Annotation (warning type Eclipse-specific) 047 @SuppressWarnings("unused") 048 private int id; 049 050 private AddressType(String displayName, int id) { 051 this.displayName = displayName; 052 this.id = id; 053 } 054 055 public String getDisplayName() { 056 return displayName; 057 } 058 059 } 060 061 public PersonEntity(Integer id) { 062 super(id); 063 } 064 065 private AddressType addressType; 066 067 public AddressType getAddressType() { 068 return addressType; 069 } 070 public void setAddressType(AddressType addressType) { 071 this.addressType = addressType; 072 } 073 074 @Override 075 // Covariant return - note return type of method in parent class. 076 public PersonEntity getMyself() { 077 return this; 078 } 079 080} 081 082// Generic type definition. 083// This can get more complex with the use of wildcards. 084abstract class BusinessService<T extends BusinessEntity> { 085 public abstract List<T> findAll(); 086 087 public abstract T loadByPrimaryKey(Long id); 088 089 090 // Static generic method 091 public static <T> T[] toArray(List<T> list, Class<T> clazz) { 092 // This construct is not allowed because the specific type of the generic 093 // is not kept at runtime - this is called erasure. 094 // T[] array = new T[](); 095 096 // Instead, pass in the class as a 'Type Token' 097 // Note that the class Class is itself genericized. 098 099 @SuppressWarnings("unchecked") // Annotation - needed for cast. 100 T[] array = (T[]) Array.newInstance(clazz, 0); 101 return list.toArray(array); 102 } 103} 104 105// Instantiation of a generic type 106public class PersonServiceImpl extends BusinessService<PersonEntity> { 107 108 @Override 109 @Deprecated // Annotation (Java standard) 110 public List<PersonEntity> findAll() { 111 // Using a list from the collections API 112 List<PersonEntity> list = new ArrayList<PersonEntity>(); 113 list.add(new PersonEntity(123)); // Autoboxing (int to Integer) 114 return list; 115 } 116 117 @Override public PersonEntity loadByPrimaryKey(Long id) { 118 List<PersonEntity> personList = findAll(); 119 for (PersonEntity person : personList) { // Enhanced for loop over list. 120 if (person.getId().equals(id)) { 121 return person; 122 } 123 } 124 125 PersonEntity[] backupArray = { 126 new PersonEntity(1), 127 new PersonEntity(2), 128 }; 129 130 for (PersonEntity person : backupArray) { // Enhanced for loop over array 131 if (person.getId().equals(id)) { 132 return person; 133 } 134 } 135 136 return null; 137 } 138 139 // Use of generic wildcard. 140 // Use of Varargs (variable arguments) 141 public Map<Integer,? extends PersonEntity> collectIntoMap(PersonEntity... people) { 142 // Using a map from the collections API 143 Map<Integer, PersonEntity> map = new HashMap<Integer,PersonEntity>(); 144 for (PersonEntity person : people) { 145 map.put(person.getId(), person); 146 } 147 return map; 148 } 149 150} 151 152// Other notes: 153// - You can define your own annotations. Used mostly by frameworks (i.e. EJB 3)