001 package com.basilv.examples.java5;
002
003 import java.lang.reflect.Array;
004 import java.util.*;
005
006
007 class 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
034 class 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.
084 abstract 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
106 public 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)