Does anyone have background on the java annotation "java.lang.Synthetic". I'm encountering it while listing annotation occurrences in a JavaEE Enterprise Application. The annotation occurs on a couple of classes in package com.sun.xml. I am finding no documentation for this annotation. Is it an official annotation, say, produced by the java compiler to indicate a synthetic accessor (see, for example, Synthetic accessor method warning)? That seems unlikely, since no documentation is available. However, placement in package "java.lang" gives the annotation somewhat of an official look.
Maybe this is what you're looking for?
http://javapapers.com/core-java/java-synthetic-class-method-field/
A perusal of ASM shows this to be a "virtual" parameter annotation added by ASM.
See:
http://asm.ow2.org/index.html
http://websvn.ow2.org/filedetails.php?repname=asm&path=%2Ftrunk%2Fasm%2Fsrc%2Forg%2Fobjectweb%2Fasm%2FClassReader.java
With:
private void readParameterAnnotations(int v, final String desc,
final char[] buf, final boolean visible, final MethodVisitor mv) {
int i;
int n = b[v++] & 0xFF;
// workaround for a bug in javac (javac compiler generates a parameter
// annotation array whose size is equal to the number of parameters in
// the Java source file, while it should generate an array whose size is
// equal to the number of parameters in the method descriptor - which
// includes the synthetic parameters added by the compiler). This work-
// around supposes that the synthetic parameters are the first ones.
int synthetics = Type.getArgumentTypes(desc).length - n;
AnnotationVisitor av;
for (i = 0; i < synthetics; ++i) {
// virtual annotation to detect synthetic parameters in MethodWriter
av = mv.visitParameterAnnotation(i, "Ljava/lang/Synthetic;", false);
if (av != null) {
av.visitEnd();
}
}
for (; i < n + synthetics; ++i) {
int j = readUnsignedShort(v);
v += 2;
for (; j > 0; --j) {
av = mv.visitParameterAnnotation(i, readUTF8(v, buf), visible);
v = readAnnotationValues(v + 2, buf, true, av);
}
}
}
Related
I am currently programing a simplified school course system using Java and I'm checking the style using CheckStyle. When I run CheckStyle on one of my classes it gives me two errors that say:
Assignment of parameter 'endTime' is not allowed.
Assignment of parameter 'startTime' is not allowed.
Ive tried multiple things to solve this issue since I can't just create a setter when I'm using that annotation.
I am also using Eclipse btw.
public void setMeetingDaysAndTime(String meetingDays, int startTime, int endTime) {
if (meetingDays == null || meetingDays.length() == 0) {
throw new IllegalArgumentException("Invalid meeting days.");
}
if ("A".equals(meetingDays)) {
this.meetingDays = meetingDays;
startTime = 0;
endTime = 0;
This is just a snippet of where my error occurs.
The following description is given for ParameterAssignment:
Disallows assignment of parameters.
Rationale: Parameter assignment is often considered poor programming
practice. Forcing developers to declare parameters as final is often
onerous. Having a check ensure that parameters are never assigned
would give the best of both worlds.
In your case,
startTime = 0;
endTime = 0;
might be an error instead of
this.startTime = 0;
this.endTime = 0;
depending on whether there are the fields startTime and endTime that you actually meant.
To prevent this error (when there is a parameter with the same name as the field), make sure to use this.<fieldName> = ...; or use the prefix new for setter method parameters:
public void setMeetingDaysAndTime(String newMeetingDays, int newStartTime, int newEndTime) {
if (newMeetingDays == null || newMeetingDays.length() == 0) {
throw new IllegalArgumentException("Invalid meeting days.");
}
if ("A".equals(newMeetingDays)) {
meetingDays = newMeetingDays;
startTime = 0;
endTime = 0;
If you really want to assign a new value to the parameter, use a variable with a descriptive name instead.
Example: Instead of re-assigning parameters like:
public void foo(String message, int value) {
message = message.trim();
value = value < 0 ? 0 : value;
bar(message, value);
use local variables instead:
public void foo(String message, int value) {
String trimmedMessage = message.trim();
int normalizedValue = value < 0 ? 0 : value;
bar(trimmedMessage, normalizedValue);
Eclipse provides the ParameterAssignment Checkstyle warning also as compiler warning (Project > Properties: Java Compiler > Errors/Warnings): Code style > Parameter assignment. And for the root cause, if this. is missing by mistake, there is the compiler warning Name shadowing and conflicts > Local variable declaration hides another field or variable which is also disabled by default.
startTime = 0;
This is re-assigning the parameter startTime.
You didn't paste a lot - if startTime is also a field, this is not assigning the field. Just like the line above it, you'd need this.startTime = 0, in order to use the field (that this. thing is needed when you shadow the field by taking in an argument that has the same name as the field).
Alternatively, turn this lint checkstyle error off, it's silly. It is attempting to avoid confusion about what that value is during the run of your method, but the fix requires making a new local variable which is itself at least as confusing. In other words, it's a stylecheck that is raising a point where the cure is worse than the disease it is pointing at.
If your intent really is to just carry on with the setMeetingDaysAndTime method as if startTime was 0, then make a new local variable:
public void setMeetingDaysAndTime(String meetingDays, int startTime_, ...) {
int startTime = startTime_;
if ( ... ) {
startTime = 0;
}
}
I have this method here:
boolean exibirAprovacao(double[][] codigoAluno, double[] codigoMateria, double nota) {
boolean aprovaAluno = false;
for(int i = 0; i < materia.length; i++) {
materia[i] = codigoAluno;
for(int j = 0; j < materia[i].length; j++) {
materia[i][j] = codigoMateria;
for(int k =0; k < materia[i][j].length; k++) {
materia[i][j][k] = nota;
if(materia[i][j][k] > 7.0) {
aprovaAluno = true;
}
}
}
}
return aprovaAluno;
}
I'm supposed to call it giving three arguments, #1 student code, #2 subject code and #3 grade. I had declared them as "double" in the method, but Eclipse highlighted it as "cannot convert from double[] to double", so it suggested me to change from this:
boolean exibirAprovacao(double codigoAluno, double codigoMateria, double nota)
To this:
boolean exibirAprovacao(double[][] codigoAluno, double[] codigoMateria, double nota)
And now Eclipse gives me an error when I'm calling my method:
aluno01.exibirAprovacao(codigoAluno, codigoMateria, nota);
Stating that
the method arguments are not applicable to the ones I'm passing
This is my array declaration:
double[][][] materia = new double[3][1][1];
This is an assignment that I have (starting Java + OO now). Any feedback is really appreciated.
First, you must review the logic of your program: If the method is supposed to find out if a certain student of a certain grade has aproved a certain subject, it should search one single value into the materia multi-array. I insist: It must search for a value, not fill in the data.
Second: Based upon the same assumption, to perform such a search, it would be enough if the method received three single parameters.
If Eclipse suggest you to change any method's firm, first understand what is the cause of the error. And do not accept suggestions without being aware of the implications (In this case, I'm afraid you shouldn't have accepted).
Is it a good practice to use properties as local variable. In cases where there are many methods which uses some variables, In each method the variable value changes. This avoids many times creating new variables and the code increases. Any suggestion?
private void method1(){
int totalLength = length1 + 10;
int totalBreath = (breath1 + breath2) + 20;
int size = (totalLength * totalLength);
System.out.println(size);
}
private void method2(){
int totalLength = length1 + 20;
int totalBreath = (breath1 + breath2) + 30;
int size = (totalLength * totalLength);
System.out.println(size);
}
private void method3(){
int totalLength = length1 + 60;
int totalBreath = (breath1 + breath2) + 10;
int size = (totalLength * totalLength);
System.out.println(size);
}
As you can see, totalLength, totalBreath, size is repeated in every method. Can i make them as fields of the class? So, i need not declare it in every method.
private void method1(){
totalLength = length1 + 10;
totalBreath = (breath1 + breath2) + 20;
size = (totalLength * totalLength);
System.out.println(size);
}
I read your question as, "When should a local variable be promoted to be a field of the class?"
The best answer is "it depends" but then again, its accuracy is quickly eclipsed by its lack of usefullness.
Fields should have a relationship to the class itself, as in is the field an attribute of the class? I include an example below to illustrate the syntax difference, but I agree with this post that it should be avoided if it pollutes the meaning of the class.
Usually you only need to have a field when you need the value of the field to be maintained between calls to different methods for a given instance of the class, with the option of making it static when the value should be maintained between method calls for all instances of the class. It will depend on several factors like shop convensions, performance goals, existing codebase, etc. so there is no single right answer without specific code. This question seems to include similar points. If you find yourself using the approach below, you might consider other approaches like refactor the behavior into a help class.
Another question asks the same question but from the perspective of a programming student.
Examples:
public class VariableScope {
int field1 = 3;
void foo() {
int a = 2;
// variable passing in width
bar1(1);
bar2(1);
// variable passing in depth
bar3(a);
// uses a field to reduce variable passing
baz1();
baz2();
}
void bar1(int param) {
System.out.println("param=" + param);
}
void bar2(int param) {
System.out.println("param=" + param);
}
void bar3(int param)
{
System.out.println("Passing param to bar4");
bar4(param);
}
void bar4(int param){
System.out.println("param=" + param);
}
void baz1() {
System.out.print("field1=" + field1);
}
void baz2() {
System.out.print("field1=" + field1);
}
}
From what it sounds like, if you're using the variable for multiple methods you're should declare the variable as a global variable. But yes, If no other method needs that variable , and you don't want to be writing a bunch of return statements you can use local variables
I suppose you mean a field by property which usually has accessor and mutator (get,set-methods).
In common you should keep the scope of a variable as small as possible. An example if you use many for loops like:
for ( int i = 0 ; i < 10 ; i++ ) {
}
and replace this by
int i;
method1() {
for ( i = 0 ; i < 10 ; i++ ) {
// some code;
}
}
method2() {
for ( i = 0 ; i < 10 ; i++ ) {
// some code;
}
}
If one thread calls method1() and another one method2() you would face a race condititon.
You can easily introduce hard to find bugs in your code.
I assume you mean something like this:
Class foo() {
int x;
public bar() {
for(x = 0; x <100; ++x) ...
} }
No, it's not good practice.
One place where it can even be harmful is in the synchronization/concurrency/multi-threaded case: if you are working with class members, they are going to need be synchronized which will eat into performance. Otherwise you risk multiple threads overwriting the value of the field and that can lead to errors in your program (likely hard to debug).
I am not finding any error in this class, but Netbeans continuously showing red symbol on that class. Class is
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package ea;
/**
*
* #author riyad
*/
import java.util.Random;
import java.util.BitSet;
public class Individual
{
BitSet variable;
double x;
double fitness;
double sharedFitness;
final int SIZE;
Random generator = new Random();
public Individual(int SIZE)
{
this.variable = new BitSet(SIZE);
this.fitness = 0;
this.sharedFitness = 0;
this.SIZE = SIZE;
for(int i=0; i<SIZE; i++)
{
if(generator.nextBoolean())
{
variable.set(i);
}
else
{
variable.clear(i);
}
}
x = Double.parseDouble(variable.toString());
}
public Individual copy()
{
Individual ind = new Individual(SIZE);
this.variable = (BitSet) ind.variable.clone();
this.fitness = ind.fitness;
this.sharedFitness = ind.sharedFitness;
this.x = ind.x;
return ind;
}
public void evaluate()
{
fitness = x * Math.sin(Math.sqrt(x));
}
public boolean getBit(int i)
{
return variable.get(i);
}
public BitSet getBitSet()
{
return variable;
}
public void setBit(int i)
{
variable.set(i);
}
public void clearBit(int i)
{
variable.clear(i);
}
public double getFitness()
{
return fitness;
}
public double sharedFitness()
{
return sharedFitness;
}
public void setSharedFitness(double fitness)
{
this.sharedFitness = fitness;
}
public void setFitness(double fitness)
{
this.fitness = fitness;
}
}
The code is compiling but getting runtime error.
Exception in thread "main" java.lang.VerifyError: (class: ea/Individual, method: <init> signature: (I)V) Constructor must call super() or this()
In another class, where Individual class is being used:
ArrayList<Individual> pop = new ArrayList<Individual>();
This where Individual class is being intantiated:
Individual temp = new Individual(STRING_SIZE);
pop.add(temp);
EDIT
I haven't renamed the file manually. All the coding was done in Netbeans. The only problem is when I am creating instance of Individual.
EDIT2
I have copied the project another place, everything is normal again. probably a bug of Netbeans or JDK
You should javap the .class file and check whether the compiler generated a call to super() near the start of your constructor.
The JVM verifier requires that any constructor (other than for Object, of course) invoke (possibly indirectly via another constructor) it's superclass's constructor. Normally the compiler inserts a call to the superclass constructor automatically if you don't do it, but it's possible that it could be confused into not doing this under some circumstances (though the code presented doesn't seem that complex).
(And, yes, you have this and ind swapped in most places in copy.)
This is probably not the problem, but your copy() method is totally messed up... Instead of copying anything, it actually just resets the original object, and returns a new empty one. If you wanted it to create copies of the object, you should do something like this:
public Individual copy()
{
Individual ind = new Individual(SIZE);
ind.variable = (BitSet) this.variable.clone();
ind.fitness = this.fitness;
ind.sharedFitness = this.sharedFitness;
ind.x = this.x;
return ind;
}
and then call it like this:
Individual newOne = oldOne.copy();
I had the same problem in Netbeans. Clean and then Build the project again solved it for me.
Hi I have the same experience with NetBeans. I was pretty mad about it, but the solution is quite easy.
You have to copy create new projects and the same classes as in the not-functional one. Then copy all the texts from the classes in old project to new project and don't forget to change package name if it isn't the same. Your work will then run :)
java.lang.VerifyError can be the result when you have compiled against a different library than you are using at runtime.
For example, this happened to me when trying to run a program that was compiled against Xerces 1, but Xerces 2 was found on the classpath. The required classes (in org.apache.* namespace) were found at runtime, so ClassNotFoundException was not the result. There had been changes to the classes and methods, so that the method signatures found at runtime did not match what was there at compile-time.
Normally, the compiler will flag problems where method signatures do not match. The JVM will verify the bytecode again when the class is loaded, and throws VerifyError when the bytecode is trying to do something that should not be allowed -- e.g. calling a method that returns String and then stores that return value in a field that holds a List. This is what I got, But still I am unable to correct it..
I was doing a Junit tutorial and I came across this normalize function that was being tested. It was defined like this:
public static String normalizeWord(String word) {
try {
int i;
Class<?> normalizerClass = Class.forName("java.text.Normalizer");
Class<?> normalizerFormClass = null;
Class<?>[] nestedClasses = normalizerClass.getDeclaredClasses();
for (i = 0; i < nestedClasses.length; i++) {
Class<?> nestedClass = nestedClasses[i];
if (nestedClass.getName().equals("java.text.Normalizer$Form")) {
normalizerFormClass = nestedClass;
}
}
assert normalizerFormClass.isEnum();
Method methodNormalize = normalizerClass.getDeclaredMethod(
"normalize",
CharSequence.class,
normalizerFormClass);
Object nfcNormalization = null;
Object[] constants = normalizerFormClass.getEnumConstants();
for (i = 0; i < constants.length; i++) {
Object constant = constants[i];
if (constant.toString().equals("NFC")) {
nfcNormalization = constant;
}
}
return (String) methodNormalize.invoke(null, word, nfcNormalization);
} catch (Exception ex) {
return null;
}
}
How does this function work? What is it actually doing?
It does the same as:
import java.text.Normalizer;
try {
return Normalizer.normalize(word, Normalizer.Form.NFC);
} catch (Exception ex) {
return null;
}
Except that all operations are performed via Reflection.
It's using reflection to call
java.text.Normalizer.normalize(word, java.text.Normalizer.Form.NFC);
Presumably to allow it to run on Java versions before 1.6 which don't have this class.
This function offers services regarding strings normalization for Unicode.
In Unicode, you can represent the same thing in many ways. For example, you have a character with accent. You can represent it joined, using one single Unicode character, or decomposed (the original letter, without accents, then the modifier - the accent).
The class comes in Java 6. For Java 5, there's a SUN proprietary class.
See class info.olteanu.utils.TextNormalizer in Phramer project (http://sourceforge.net/projects/phramer/ , www.phramer.org ) for a way to get a normalizer both in Java 5 (SUN JDK) and in Java 6, without any compilation issues (the code will compile in any version >= 5 and the code will run in both JVMs, although SUN discarded the Java 5 proprietary class).