Skip to content

Commit f66228e

Browse files
authored
Fix unchecked warnings (#3083)
This change fixes "unchecked or unsafe operations" from the build. Example of warning: ``` Note: /home/runner/work/java/java/exercises/concept/lasagna/src/test/java/utils/ReflectionProxy.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. ``` See https://github.com/exercism/java/actions/runs/21096072319/job/60673664241#step:4:129 [no important files changed]
1 parent 108b0b1 commit f66228e

8 files changed

Lines changed: 68 additions & 58 deletions

File tree

exercises/concept/lasagna/src/test/java/utils/Lasagna.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,19 @@ public String getTargetClassName() {
88
}
99

1010
public int expectedMinutesInOven() {
11-
return invokeMethod("expectedMinutesInOven", new Class[]{});
11+
return invokeMethod("expectedMinutesInOven", Integer.class, new Class[]{});
1212
}
1313

1414
public int remainingMinutesInOven(int actualMinutes) {
15-
return invokeMethod("remainingMinutesInOven", new Class[]{int.class}, actualMinutes);
15+
return invokeMethod("remainingMinutesInOven", Integer.class, new Class[]{int.class}, actualMinutes);
1616
}
1717

1818
public int preparationTimeInMinutes(int amountLayers) {
19-
return invokeMethod("preparationTimeInMinutes", new Class[]{int.class}, amountLayers);
19+
return invokeMethod("preparationTimeInMinutes", Integer.class, new Class[]{int.class}, amountLayers);
2020
}
2121

2222
public int totalTimeInMinutes(int amountLayers, int actualMinutes) {
23-
return invokeMethod("totalTimeInMinutes", new Class[]{int.class, int.class}, amountLayers, actualMinutes);
23+
return invokeMethod("totalTimeInMinutes", Integer.class, new Class[]{int.class, int.class},
24+
amountLayers, actualMinutes);
2425
}
2526
}

exercises/concept/lasagna/src/test/java/utils/ReflectionProxy.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,26 +101,28 @@ public boolean isMethodReturnType(Class<?> returnType, String name, Class<?>...
101101
/**
102102
* Invokes a method from the target instance
103103
* @param methodName The name of the method
104+
* @param returnType The class representing the expected return type
104105
* @param parameterTypes The list of parameter types
105106
* @param parameterValues The list with values for the method parameters
106107
* @param <T> The result type we expect the method to be
107108
* @return The value returned by the method
108109
*/
109-
protected <T> T invokeMethod(String methodName, Class<?>[] parameterTypes, Object... parameterValues) {
110+
protected <T> T invokeMethod(String methodName, Class<T> returnType, Class<?>[] parameterTypes,
111+
Object... parameterValues) {
110112
if (target == null) {
111113
return null;
112114
}
113115
try {
114116
// getDeclaredMethod is used to get protected/private methods
115117
Method method = target.getClass().getDeclaredMethod(methodName, parameterTypes);
116118
method.setAccessible(true);
117-
return (T) method.invoke(target, parameterValues);
119+
return returnType.cast(method.invoke(target, parameterValues));
118120
} catch (NoSuchMethodException e) {
119121
try {
120122
// try getting it from parent class, but only public methods will work
121123
Method method = target.getClass().getMethod(methodName, parameterTypes);
122124
method.setAccessible(true);
123-
return (T) method.invoke(target, parameterValues);
125+
return returnType.cast(method.invoke(target, parameterValues));
124126
} catch (Exception ex) {
125127
return null;
126128
}
@@ -381,7 +383,7 @@ public int hashCode() {
381383
* @return The result of 'toString' from the target instance
382384
*/
383385
public String toString() {
384-
return invokeMethod("toString", new Class[]{ });
386+
return invokeMethod("toString", String.class, new Class[]{ });
385387
}
386388

387389
/**
@@ -390,14 +392,14 @@ public String toString() {
390392
* @param <T> The type we are expecting it to be
391393
* @return The value of the property (if it exists)
392394
*/
393-
protected <T> T getPropertyValue(String propertyName) {
395+
protected <T> T getPropertyValue(String propertyName, Class<T> propertyType) {
394396
if (target == null || !hasProperty(propertyName)) {
395397
return null;
396398
}
397399
try {
398400
Field field = target.getClass().getDeclaredField(propertyName);
399401
field.setAccessible(true);
400-
return (T) field.get(target);
402+
return propertyType.cast(field.get(target));
401403
} catch (Exception e) {
402404
return null;
403405
}

exercises/concept/wizards-and-warriors-2/src/test/java/GameMasterProxy.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,25 @@ public String getTargetClassName() {
1212
}
1313

1414
public String describe(Character character) {
15-
return invokeMethod("describe", new Class[] { Character.class }, character);
15+
return invokeMethod("describe", String.class, new Class[] { Character.class }, character);
1616
}
1717

1818
public String describe(Destination character) {
19-
return invokeMethod("describe", new Class[] { Destination.class }, character);
19+
return invokeMethod("describe", String.class, new Class[] { Destination.class }, character);
2020
}
2121

2222
public String describe(TravelMethod character) {
23-
return invokeMethod("describe", new Class[] { TravelMethod.class }, character);
23+
return invokeMethod("describe", String.class, new Class[] { TravelMethod.class }, character);
2424
}
2525

2626
public String describe(Character character, Destination destination, TravelMethod travelMethod) {
27-
return invokeMethod("describe", new Class[] { Character.class, Destination.class, TravelMethod.class },
27+
return invokeMethod("describe", String.class,
28+
new Class[] { Character.class, Destination.class, TravelMethod.class },
2829
character, destination, travelMethod);
2930
}
3031

3132
public String describe(Character character, Destination destination) {
32-
return invokeMethod("describe", new Class[] { Character.class, Destination.class }, character, destination);
33+
return invokeMethod("describe", String.class, new Class[] { Character.class, Destination.class },
34+
character, destination);
3335
}
3436
}

exercises/concept/wizards-and-warriors-2/src/test/java/ReflectionProxy.java

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,14 @@ public boolean isMethodReturnType(Class<?> returnType, String name, Class<?>...
117117
* Invokes a method from the target instance
118118
*
119119
* @param methodName The name of the method
120+
* @param returnType The class representing the expected return type
120121
* @param parameterTypes The list of parameter types
121122
* @param parameterValues The list with values for the method parameters
122123
* @param <T> The result type we expect the method to be
123124
* @return The value returned by the method
124125
*/
125-
protected <T> T invokeMethod(String methodName, Class<?>[] parameterTypes, Object... parameterValues) {
126+
protected <T> T invokeMethod(String methodName, Class<T> returnType, Class<?>[] parameterTypes,
127+
Object... parameterValues) {
126128
if (target == null) {
127129
throw new UnsupportedOperationException();
128130
}
@@ -131,12 +133,12 @@ protected <T> T invokeMethod(String methodName, Class<?>[] parameterTypes, Objec
131133
// getDeclaredMethod is used to get protected/private methods
132134
Method method = target.getClass().getDeclaredMethod(methodName, parameterTypes);
133135
method.setAccessible(true);
134-
return (T) method.invoke(target, parameterValues);
136+
return returnType.cast(method.invoke(target, parameterValues));
135137
} catch (NoSuchMethodException e) {
136138
// try getting it from parent class, but only public methods will work
137139
Method method = target.getClass().getMethod(methodName, parameterTypes);
138140
method.setAccessible(true);
139-
return (T) method.invoke(target, parameterValues);
141+
return returnType.cast(method.invoke(target, parameterValues));
140142
}
141143
} catch (Exception e) {
142144
throw new UnsupportedOperationException(e);
@@ -360,7 +362,6 @@ public boolean isConstructorPublic(Class<?>... parameterTypes) {
360362

361363
/**
362364
* Proxy for the 'equals' method
363-
*
364365
* @param obj The ReflexionProxy object you want to compare against
365366
* @return True if both targets are equal, false otherwise
366367
*/
@@ -379,7 +380,6 @@ public boolean equals(Object obj) {
379380

380381
/**
381382
* Proxy for the 'hashCode' method
382-
*
383383
* @return The hashCode from the target class
384384
*/
385385
public int hashCode() {
@@ -397,36 +397,33 @@ public int hashCode() {
397397

398398
/**
399399
* Proxy for the 'toString' method from the target class
400-
*
401400
* @return The result of 'toString' from the target instance
402401
*/
403402
public String toString() {
404-
return invokeMethod("toString", new Class[]{});
403+
return invokeMethod("toString", String.class, new Class[]{ });
405404
}
406405

407406
/**
408407
* Gets a property value from the target instance (if it exists)
409-
*
410408
* @param propertyName The name of the property
411-
* @param <T> The type we are expecting it to be
409+
* @param <T> The type we are expecting it to be
412410
* @return The value of the property (if it exists)
413411
*/
414-
protected <T> T getPropertyValue(String propertyName) {
412+
protected <T> T getPropertyValue(String propertyName, Class<T> propertyType) {
415413
if (target == null || !hasProperty(propertyName)) {
416414
return null;
417415
}
418416
try {
419417
Field field = target.getClass().getDeclaredField(propertyName);
420418
field.setAccessible(true);
421-
return (T) field.get(target);
419+
return propertyType.cast(field.get(target));
422420
} catch (Exception e) {
423421
return null;
424422
}
425423
}
426424

427425
/**
428426
* Checks if the target class is abstract
429-
*
430427
* @return True if the target class exists and is abstract, false otherwise
431428
*/
432429
public boolean isAbstract() {
@@ -439,7 +436,6 @@ public boolean isAbstract() {
439436

440437
/**
441438
* Checks if the target class extends another
442-
*
443439
* @param className The fully qualified name of the class it should extend
444440
* @return True if the target class extends the specified one, false otherwise
445441
*/
@@ -458,7 +454,6 @@ public boolean extendsClass(String className) {
458454

459455
/**
460456
* Checks if the target class is an interface
461-
*
462457
* @return True if the target class exists and is an interface, false otherwise
463458
*/
464459
public boolean isInterface() {
@@ -471,8 +466,7 @@ public boolean isInterface() {
471466

472467
/**
473468
* Checks if a method is abstract
474-
*
475-
* @param name The name of the method
469+
* @param name The name of the method
476470
* @param parameterTypes The list of method parameter types
477471
* @return True if the method exists and is abstract, false otherwise
478472
*/
@@ -491,8 +485,7 @@ public boolean isMethodAbstract(String name, Class<?>... parameterTypes) {
491485

492486
/**
493487
* Checks if a method is protected
494-
*
495-
* @param name The name of the method
488+
* @param name The name of the method
496489
* @param parameterTypes The list of method parameter types
497490
* @return True if the method exists and is protected, false otherwise
498491
*/
@@ -511,3 +504,4 @@ public boolean isMethodProtected(String name, Class<?>... parameterTypes) {
511504

512505
//endregion
513506
}
507+

exercises/concept/wizards-and-warriors/src/test/java/ReflectionProxy.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,26 +99,28 @@ public boolean isMethodReturnType(Class<?> returnType, String name, Class<?>...
9999
/**
100100
* Invokes a method from the target instance
101101
* @param methodName The name of the method
102+
* @param returnType The class representing the expected return type
102103
* @param parameterTypes The list of parameter types
103104
* @param parameterValues The list with values for the method parameters
104105
* @param <T> The result type we expect the method to be
105106
* @return The value returned by the method
106107
*/
107-
protected <T> T invokeMethod(String methodName, Class<?>[] parameterTypes, Object... parameterValues) {
108+
protected <T> T invokeMethod(String methodName, Class<T> returnType, Class<?>[] parameterTypes,
109+
Object... parameterValues) {
108110
if (target == null) {
109111
return null;
110112
}
111113
try {
112114
// getDeclaredMethod is used to get protected/private methods
113115
Method method = target.getClass().getDeclaredMethod(methodName, parameterTypes);
114116
method.setAccessible(true);
115-
return (T) method.invoke(target, parameterValues);
117+
return returnType.cast(method.invoke(target, parameterValues));
116118
} catch (NoSuchMethodException e) {
117119
try {
118120
// try getting it from parent class, but only public methods will work
119121
Method method = target.getClass().getMethod(methodName, parameterTypes);
120122
method.setAccessible(true);
121-
return (T) method.invoke(target, parameterValues);
123+
return returnType.cast(method.invoke(target, parameterValues));
122124
} catch (Exception ex) {
123125
return null;
124126
}
@@ -379,23 +381,24 @@ public int hashCode() {
379381
* @return The result of 'toString' from the target instance
380382
*/
381383
public String toString() {
382-
return invokeMethod("toString", new Class[]{ });
384+
return invokeMethod("toString", String.class, new Class[]{ });
383385
}
384386

385387
/**
386388
* Gets a property value from the target instance (if it exists)
387389
* @param propertyName The name of the property
390+
* @param propertyType The class representing the property's type
388391
* @param <T> The type we are expecting it to be
389392
* @return The value of the property (if it exists)
390393
*/
391-
protected <T> T getPropertyValue(String propertyName) {
394+
protected <T> T getPropertyValue(String propertyName, Class<T> propertyType) {
392395
if (target == null || !hasProperty(propertyName)) {
393396
return null;
394397
}
395398
try {
396399
Field field = target.getClass().getDeclaredField(propertyName);
397400
field.setAccessible(true);
398-
return (T) field.get(target);
401+
return propertyType.cast(field.get(target));
399402
} catch (Exception e) {
400403
return null;
401404
}

exercises/concept/wizards-and-warriors/src/test/java/WarriorProxy.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ public String getTargetClassName() {
66
}
77

88
public String toString() {
9-
return invokeMethod("toString", new Class[0]);
9+
return invokeMethod("toString", String.class, new Class[0]);
1010
}
1111

1212
boolean isVulnerable() {
13-
return invokeMethod("isVulnerable", new Class[0]);
13+
return invokeMethod("isVulnerable", Boolean.class, new Class[0]);
1414
}
1515

1616
int getDamagePoints(Fighter target) {
17-
return invokeMethod("getDamagePoints", new Class[]{Fighter.class}, target);
17+
return invokeMethod("getDamagePoints", Integer.class, new Class[]{Fighter.class}, target);
1818
}
1919
}

exercises/concept/wizards-and-warriors/src/test/java/WizardProxy.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,18 @@ public String getTargetClassName() {
66
}
77

88
public String toString() {
9-
return invokeMethod("toString", new Class[0]);
9+
return invokeMethod("toString", String.class, new Class[0]);
1010
}
1111

1212
boolean isVulnerable() {
13-
return invokeMethod("isVulnerable", new Class[0]);
13+
return invokeMethod("isVulnerable", Boolean.class, new Class[0]);
1414
}
1515

1616
int getDamagePoints(Fighter target) {
17-
return invokeMethod("getDamagePoints", new Class[]{Fighter.class}, target);
17+
return invokeMethod("getDamagePoints", Integer.class, new Class[]{Fighter.class}, target);
1818
}
1919

2020
void prepareSpell() {
21-
invokeMethod("prepareSpell", new Class[0]);
21+
invokeMethod("prepareSpell", Void.class, new Class[0]);
2222
}
2323
}

0 commit comments

Comments
 (0)